Submission #1030013

#TimeUsernameProblemLanguageResultExecution timeMemory
1030013avighnaProgression (NOI20_progression)C++17
74 / 100
3057 ms103012 KiB
#include <bits/stdc++.h> typedef long long ll; class Node { public: ll pref, suff, max; ll ele; ll size; Node(ll pref, ll suff, ll max, ll ele, ll size) : pref(pref), suff(suff), max(max), ele(ele), size(size) {} Node() : pref(0), suff(0), max(0), ele(-1), size(0) {} bool operator==(const Node &other) { return pref == other.pref and suff == other.suff and max == other.max and ele == other.ele and size == other.size; } }; class SegmentTree { public: std::vector<Node> seg; std::vector<bool> lazy; ll n; SegmentTree(ll n) { this->n = n; seg.resize(4 * n); lazy.resize(8 * n); } Node idt() { return Node(0, 0, 0, -1, 0); } Node f(Node a, Node b) { if (a == idt()) { return b; } if (b == idt()) { return a; } Node ans; ans.pref = a.pref; if (a.pref == a.size) { ans.pref += b.pref; } ans.suff = b.suff; if (b.suff == b.size) { ans.suff += a.suff; } ans.max = std::max(ans.max, ans.suff); ans.max = std::max(ans.max, ans.pref); ans.max = std::max(ans.max, a.suff + b.pref); ans.max = std::max(ans.max, a.max); ans.max = std::max(ans.max, b.max); ans.ele = a.ele; ans.size = a.size + b.size; return ans; } void construct(std::vector<ll> &a, ll v, ll tl, ll tr) { if (tl == tr) { if (a[tl] == 0) { seg[v] = Node(1, 1, 1, a[tl], 1); } else { seg[v] = Node(0, 0, 0, a[tl], 1); } return; } ll tm = (tl + tr) / 2; construct(a, 2 * v, tl, tm); construct(a, 2 * v + 1, tm + 1, tr); seg[v] = f(seg[2 * v], seg[2 * v + 1]); } void lazy_update(ll v, ll tl, ll tr) { if (lazy[v]) { lazy[v] = false; ll size = tr - tl + 1; seg[v] = Node(size, size, size, 0, size); lazy[2 * v] = lazy[2 * v + 1] = true; } } Node query(ll v, ll tl, ll tr, ll l, ll r) { lazy_update(v, tl, tr); if (tl > tr || l > r || tr < l || r < tl) { return idt(); } if (l <= tl && tr <= r) { return seg[v]; } ll tm = (tl + tr) / 2; return f(query(2 * v, tl, tm, l, r), query(2 * v + 1, tm + 1, tr, l, r)); } Node query(ll l, ll r) { return query(1, 0, n, l, r); } void update(ll v, ll tl, ll tr, ll idx, ll del) { lazy_update(v, tl, tr); if (tl > tr || (!(tl <= idx && idx <= tr))) { return; } if (tl != tr) { ll tm = (tl + tr) / 2; update(2 * v, tl, tm, idx, del); update(2 * v + 1, tm + 1, tr, idx, del); seg[v] = f(seg[2 * v], seg[2 * v + 1]); } else { seg[v].ele += del; if (seg[v].ele == 0) { seg[v] = Node(1, 1, 1, seg[v].ele, 1); } else { seg[v] = Node(0, 0, 0, seg[v].ele, 1); } } } void update(ll idx, ll del) { update(1, 0, n, idx, del); } void zero_range(ll v, ll tl, ll tr, ll l, ll r) { lazy_update(v, tl, tr); if (tl > tr || l > r || tr < l || r < tl) { return; } if (l <= tl && tr <= r) { ll size = tr - tl + 1; seg[v] = Node(size, size, size, 0, size); lazy[2 * v] = lazy[2 * v + 1] = true; return; } ll tm = (tl + tr) / 2; zero_range(2 * v, tl, tm, l, r); zero_range(2 * v + 1, tm + 1, tr, l, r); } void zero_range(ll l, ll r) { zero_range(1, 0, n, l, r); } }; class LazySegmentTree { private: enum type { ADD, SET }; std::vector<std::array<ll, 2>> lazy; public: std::vector<ll> seg; ll n; ll f(ll a, ll b) { return a + b; } // For a bitwise AND, this would be 1, since x AND x = x (and not 2x) ll f_update_range(ll size) { return size; } ll idt() { return 0; } LazySegmentTree(ll n) { this->n = n; seg.resize(4 * n, idt()); lazy.resize(8 * n); for (ll i = 0; i < 8 * n; ++i) { lazy[i][SET] = -1; } } void do_lazy_update(ll v, ll size) { if (lazy[v][SET] != -1) { seg[v] = lazy[v][SET] * size; lazy[2 * v][SET] = lazy[2 * v + 1][SET] = lazy[v][SET]; lazy[2 * v][ADD] = lazy[2 * v + 1][ADD] = 0; lazy[v][SET] = -1; } if (lazy[v][ADD] != 0) { seg[v] += lazy[v][ADD] * size; lazy[2 * v][ADD] += lazy[v][ADD]; lazy[2 * v + 1][ADD] += lazy[v][ADD]; lazy[v][ADD] = 0; } } void add(ll v, ll tl, ll tr, ll l, ll r, ll delta) { ll size = f_update_range(tr - tl + 1); do_lazy_update(v, size); // [tl, tr] ... [l, r] or [l, r] ... [tl, tr] if (tr < l || r < tl || l > r || tl > tr) { return; } // [l, [tl, tr], r] if (l <= tl && tr <= r) { seg[v] += delta * size; lazy[2 * v][ADD] += delta; lazy[2 * v + 1][ADD] += delta; return; } ll tm = (tl + tr) / 2; add(2 * v, tl, tm, l, r, delta); add(2 * v + 1, tm + 1, tr, l, r, delta); seg[v] = f(seg[2 * v], seg[2 * v + 1]); } void add(ll l, ll r, ll delta) { add(1, 0, n, l, r, delta); } void add(ll idx, ll delta) { add(idx, idx, delta); } void set(ll v, ll tl, ll tr, ll l, ll r, ll x) { ll size = f_update_range(tr - tl + 1); do_lazy_update(v, size); // [tl, tr] ... [l, r] or [l, r] ... [tl, tr] if (tr < l || r < tl || l > r || tl > tr) { return; } // [l, [tl, tr], r] if (l <= tl && tr <= r) { seg[v] = x * size; lazy[2 * v][SET] = lazy[2 * v + 1][SET] = x; lazy[2 * v][ADD] = lazy[2 * v + 1][ADD] = 0; return; } ll tm = (tl + tr) / 2; set(2 * v, tl, tm, l, r, x); set(2 * v + 1, tm + 1, tr, l, r, x); seg[v] = f(seg[2 * v], seg[2 * v + 1]); } void set(ll l, ll r, ll x) { set(1, 0, n, l, r, x); } void set(ll idx, ll x) { set(idx, idx, x); } ll query(ll v, ll tl, ll tr, ll l, ll r) { do_lazy_update(v, f_update_range(tr - tl + 1)); // [tl, tr] ... [l, r] or [l, r] ... [tl, tr] if (tr < l || r < tl || l > r || tl > tr) { return idt(); } // [l, [tl, tr], r] if (l <= tl && tr <= r) { return seg[v]; } ll tm = (tl + tr) / 2; return f(query(2 * v, tl, tm, l, r), query(2 * v + 1, tm + 1, tr, l, r)); } ll query(ll l, ll r) { return query(1, 0, n, l, r); } }; int main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); ll n, q; std::cin >> n >> q; std::vector<ll> d(n + 1); for (ll i = 0; i < n; ++i) { std::cin >> d[i]; } std::vector<ll> diff(n + 1); std::adjacent_difference(d.begin(), d.end(), diff.begin()); std::vector<ll> diff_diff(n + 1); std::adjacent_difference(diff.begin(), diff.end(), diff_diff.begin()); SegmentTree tree(n); LazySegmentTree diff_tree(n); tree.construct(diff_diff, 1, 0, n); for (ll i = 0; i < n; ++i) { diff_tree.add(i, diff[i]); } auto diff_update = [&](ll l, ll r, ll s, ll c) { diff_tree.add(l, s); diff_tree.add(r + 1, -s - (r - l) * c); if (l + 1 <= r) { diff_tree.add(l + 1, r, c); } }; auto update = [&](ll l, ll r, ll s, ll c) { tree.update(l, s); tree.update(l + 1, -s); tree.update(r + 1, -s); if (r + 2 <= n) { tree.update(r + 2, s); } if (l != r) { tree.update(l + 1, c); tree.update(r + 1, -c - (r - l) * c); if (r + 2 <= n) { tree.update(r + 2, (r - l) * c); } } }; auto set_to_zero = [&](ll l) { ll pref_1 = diff_tree.query(0, l); diff_tree.add(l, -pref_1); diff_tree.add(l + 1, pref_1); tree.update(l, -pref_1); tree.update(l + 1, 2 * pref_1); tree.update(l + 2, -pref_1); }; while (q--) { ll t; std::cin >> t; ll l, r; std::cin >> l >> r; --l, --r; if (t == 1) { ll s, c; std::cin >> s >> c; update(l, r, s, c); diff_update(l, r, s, c); } else if (t == 2) { ll s, c; std::cin >> s >> c; // if (r - l <= 2) { // } else { // ll pref_1 = diff_tree.query(0, l); // ll pref_2 = diff_tree.query(0, r + 1); // diff_tree.add(l, -pref_1); // diff_tree.set(l + 1, r, 0); // diff_tree.add(r + 1, pref_2); // tree.update(l + 1, -diff_tree.query(l + 1, l + 1)); // tree.zero_range(l + 2, r); // tree.update(r + 1, diff_tree.query(r + 1, r + 1)); // } for (ll i = l; i <= r; ++i) { set_to_zero(i); } update(l, r, s, c); diff_update(l, r, s, c); } else { if (l + 2 > r) { std::cout << r - l + 1 << '\n'; } else { std::cout << tree.query(l + 2, r).max + 2 << '\n'; } } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...