Submission #1314649

#TimeUsernameProblemLanguageResultExecution timeMemory
1314649joshjuiceProgression (NOI20_progression)C++20
100 / 100
961 ms138100 KiB
#include <bits/stdc++.h> using namespace std; #define int long long #define rep(x, a, b) for(auto x=a;(a<b?x<b:x>b);(a<b?x++:x--)) #define all(a) a.begin(), a.end() #define srtvc(a) sort(all(a)) #define bcsrtvc(a) sort(all(a), greater<__typeof__(a[0])>()) #define ppf pop_front #define ppb pop_back #define pf push_front #define pb push_back #define ef emplace_front #define eb emplace_back #define fr first #define sc second #define pq priority_queue #define pii pair<int, int> #define iii tuple<int, int, int> #define vc vector #define dq deque #define stk stack #define umap unordered_map #define sz(a) a.size() #define mnto(x,y) x = min(x, (__typeof__(x))y) #define mxto(x,y) x = max(x, (__typeof__(x))y) #define setval(arr, x) memset(arr, x, sizeof(arr)) template<typename T> using vv = vc<vc<T>>; struct NodeA { int lv, rv, len, pref, suff, best; NodeA(): lv(0), rv(0), len(0), pref(0), suff(0), best(0) {} }; struct SegA { int n; vc<NodeA> st; vc<int> lazyAdd; vc<pair<bool, int>> lazyAssign; SegA(int _n = 0) { init(_n); } void init(int _n) { n = max(0LL, _n); if (n == 0) return; st.assign(4*n+5, NodeA()); lazyAdd.assign(4*n+5, 0); lazyAssign.assign(4*n+5, {0, 0}); } NodeA merge(const NodeA &L, const NodeA &R) { if (L.len == 0) return R; if (R.len == 0) return L; NodeA p; p.len = L.len + R.len; p.lv = L.lv; p.rv = R.rv; p.pref = L.pref; if (L.pref == L.len && L.rv == R.lv) p.pref = L.len + R.pref; p.suff = R.suff; if (R.suff == R.len && L.rv == R.lv) p.suff = R.len + L.suff; p.best = max(L.best, R.best); if (L.rv == R.lv) mxto(p.best, L.suff + R.pref); return p; } void applyAssign(int p, int l, int r, int val) { NodeA &nd = st[p]; nd.lv = nd.rv = val; nd.pref = nd.suff = nd.best = nd.len; lazyAssign[p] = {1, val}; lazyAdd[p] = 0; } void applyAdd(int p, int l, int r, int v) { NodeA &nd = st[p]; nd.lv += v; nd.rv += v; if (lazyAssign[p].fr) lazyAssign[p].sc += v; else lazyAdd[p] += v; } void build_from_array(const vc<int> &a) { if (n == 0) return; build(1, 1, n, a); } void build(int p, int l, int r, const vc<int> &a) { lazyAdd[p] = 0; lazyAssign[p] = {0, 0}; if (l == r) { NodeA &nd = st[p]; nd.len = 1; nd.lv = nd.rv = a[l]; nd.pref = nd.suff = nd.best = 1; return; } int m = (l + r)/2; build(p<<1, l, m, a); build(p<<1|1, m+1, r, a); st[p] = merge(st[p<<1], st[p<<1|1]); } void push(int p, int l, int r) { if (l == r) return; int lc = p<<1, rc = p<<1|1; if (lazyAssign[p].fr) { applyAssign(lc, l, (l+r)/2, lazyAssign[p].sc); applyAssign(rc, (l+r)/2+1, r, lazyAssign[p].sc); lazyAssign[p] = {0, 0}; } if (lazyAdd[p] != 0) { int v = lazyAdd[p]; applyAdd(lc, l, (l+r)/2, v); applyAdd(rc, (l+r)/2+1, r, v); lazyAdd[p] = 0; } } void rangeAssign(int L, int R, int val) { if (n == 0) return; rangeAssign(1, 1, n, L, R, val); } void rangeAssign(int p, int l, int r, int L, int R, int val) { if (R < l || r < L) return; if (L <= l && r <= R) { applyAssign(p, l, r, val); return; } push(p, l, r); int m = (l + r)/2; rangeAssign(p<<1, l, m, L, R, val); rangeAssign(p<<1|1, m+1, r, L, R, val); st[p] = merge(st[p<<1], st[p<<1|1]); } void rangeAdd(int L, int R, int val) { if (n == 0) return; rangeAdd(1, 1, n, L, R, val); } void rangeAdd(int p, int l, int r, int L, int R, int val) { if (R < l || r < L) return; if (L <= l && r <= R) { applyAdd(p, l, r, val); return; } push(p, l, r); int m = (l + r)/2; rangeAdd(p<<1, l, m, L, R, val); rangeAdd(p<<1|1, m+1, r, L, R, val); st[p] = merge(st[p<<1], st[p<<1|1]); } NodeA queryRange(int L, int R) { if (n == 0) return NodeA(); return queryRange(1, 1, n, L, R); } NodeA queryRange(int p, int l, int r, int L, int R) { if (R < l || r < L) return NodeA(); if (L <= l && r <= R) return st[p]; push(p, l, r); int m = (l + r)/2; NodeA a = queryRange(p<<1, l, m, L, R); NodeA b = queryRange(p<<1|1, m+1, r, L, R); return merge(a, b); } }; struct SegD { int n; struct Tag { bool hasAssign; int A, B, addA, addB; Tag(): hasAssign(0), A(0), B(0), addA(0), addB(0) {} }; vc<Tag> lazy; SegD(int _n = 0) { init(_n); } void init(int _n) { n = _n; lazy.assign(4*n+5, Tag()); } void applyAssign(int p, int a, int b) { lazy[p].hasAssign = 1; lazy[p].A = a; lazy[p].B = b; lazy[p].addA = lazy[p].addB = 0; } void applyAdd(int p, int da, int db) { if (lazy[p].hasAssign) { lazy[p].A += da; lazy[p].B += db; } else { lazy[p].addA += da; lazy[p].addB += db; } } void push(int p, int l, int r) { int m = (l + r)/2; int lc = p<<1, rc = p<<1|1; if (lazy[p].hasAssign) { int A = lazy[p].A, B = lazy[p].B; applyAssign(lc, A, B); applyAssign(rc, A, B); lazy[p].hasAssign = 0; } if (lazy[p].addA != 0 || lazy[p].addB != 0) { int addA = lazy[p].addA, addB = lazy[p].addB; applyAdd(lc, addA, addB); applyAdd(rc, addA, addB); lazy[p].addA = lazy[p].addB = 0; } } void build_from_D(const vc<int> &D) { if (n == 0) return; build(1, 1, n, D); } void build(int p, int l, int r, const vc<int> &D) { lazy[p] = Tag(); if (l == r) { applyAssign(p, D[l], 0); return; } int m = (l + r)/2; build(p<<1, l, m, D); build(p<<1|1, m+1, r, D); } void rangeAddLinear(int L, int R, int alpha, int beta) { if (L > R) return; rangeAddLinear(1, 1, n, L, R, alpha, beta); } void rangeAddLinear(int p, int l, int r, int L, int R, int alpha, int beta) { if (R < l || r < L) return; if (L <= l && r <= R) { applyAdd(p, alpha, beta); return; } push(p, l, r); int m = (l + r)/2; rangeAddLinear(p<<1, l, m, L, R, alpha, beta); rangeAddLinear(p<<1|1, m+1, r, L, R, alpha, beta); } void rangeAssignLinear(int L, int R, int alpha, int beta) { if (L > R) return; rangeAssignLinear(1, 1, n, L, R, alpha, beta); } void rangeAssignLinear(int p, int l, int r, int L, int R, int alpha, int beta) { if (R < l || r < L) return; if (L <= l && r <= R) { applyAssign(p, alpha, beta); return; } push(p, l, r); int m = (l + r)/2; rangeAssignLinear(p<<1, l, m, L, R, alpha, beta); rangeAssignLinear(p<<1|1, m+1, r, L, R, alpha, beta); } int pointQuery(int pos) { return pointQuery(1, 1, n, pos); } int pointQuery(int p, int l, int r, int pos) { if (l == r) { int res = 0; if (lazy[p].hasAssign) res = lazy[p].A + lazy[p].B * l; else res = lazy[p].addA + lazy[p].addB * l; return res; } push(p, l, r); int m = (l + r)/2; if (pos <= m) return pointQuery(p<<1, l, m, pos); else return pointQuery(p<<1|1, m+1, r, pos); } }; int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int N, Q; cin >> N >> Q; vc<int> D(N+1); rep(i, 1, N+1) cin >> D[i]; if (N == 1) { rep(i, 0, Q) { int t; cin >> t; if (t == 1 || t == 2) { int L, R, S, C; cin >> L >> R >> S >> C; } else { int L, R; cin >> L >> R; cout << 1 << '\n'; } } return 0; } vc<int> A(N); rep(i, 1, N) A[i] = D[i+1] - D[i]; SegA segA(N-1); segA.build_from_array(A); SegD segD(N); segD.build_from_D(D); rep(qi, 0, Q) { int type; cin >> type; if (type == 1) { int L, R, S, C; cin >> L >> R >> S >> C; int alpha = S - L*C; int beta = C; segD.rangeAddLinear(L, R, alpha, beta); if (L < R) segA.rangeAdd(L, R-1, C); if (L > 1) segA.rangeAdd(L-1, L-1, S); if (R < N) { int fR = S + (R-L)*C; segA.rangeAdd(R, R, -fR); } } else if (type == 2) { int L, R, S, C; cin >> L >> R >> S >> C; int alpha = S - L*C; int beta = C; segD.rangeAssignLinear(L, R, alpha, beta); if (L < R) segA.rangeAssign(L, R-1, C); if (L > 1) { int D_Lminus1 = segD.pointQuery(L-1); int newA = S - D_Lminus1; segA.rangeAssign(L-1, L-1, newA); } if (R < N) { int D_Rplus1 = segD.pointQuery(R+1); int DR = S + (R-L)*C; int newA = D_Rplus1 - DR; segA.rangeAssign(R, R, newA); } } else if (type == 3) { int L, R; cin >> L >> R; if (L == R) { cout << 1 << '\n'; continue; } NodeA ans = segA.queryRange(L, R-1); cout << ans.best+1 << '\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...