Submission #1181880

#TimeUsernameProblemLanguageResultExecution timeMemory
1181880mehmetkaganProgression (NOI20_progression)C++20
0 / 100
621 ms141708 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define int ll struct SegA { int n; vector<ll> base; vector<bool> lazySet; vector<ll> lazySetA, lazySetB, lazyAddA, lazyAddB; SegA(int n, const vector<ll>& init): n(n), base(init) { lazySet.assign(4*n, false); lazySetA.assign(4*n, 0); lazySetB.assign(4*n, 0); lazyAddA.assign(4*n, 0); lazyAddB.assign(4*n, 0); } void pushDown(int idx, int l, int r) { int m = (l+r)/2, lc = idx*2, rc = idx*2+1; if(lazySet[idx]){ lazySet[lc] = lazySet[rc] = true; lazySetA[lc] = lazySetA[idx]; lazySetB[lc] = lazySetB[idx]; lazySetA[rc] = lazySetA[idx]; lazySetB[rc] = lazySetB[idx]; lazyAddA[lc] = lazyAddB[lc] = 0; lazyAddA[rc] = lazyAddB[rc] = 0; lazySet[idx] = false; lazySetA[idx] = lazySetB[idx] = 0; } if(lazyAddA[idx] != 0 || lazyAddB[idx] != 0){ lazyAddA[lc] += lazyAddA[idx]; lazyAddB[lc] += lazyAddB[idx]; lazyAddA[rc] += lazyAddA[idx]; lazyAddB[rc] += lazyAddB[idx]; lazyAddA[idx] = lazyAddB[idx] = 0; } } void update(int idx, int l, int r, int ql, int qr, bool setOp, ll A_val, ll B_val) { if(ql > r || qr < l) return; if(ql <= l && r <= qr){ if(setOp){ lazySet[idx] = true; lazySetA[idx] = A_val; lazySetB[idx] = B_val; lazyAddA[idx] = lazyAddB[idx] = 0; } else { if(lazySet[idx]){ lazySetA[idx] += A_val; lazySetB[idx] += B_val; } else { lazyAddA[idx] += A_val; lazyAddB[idx] += B_val; } } return; } pushDown(idx, l, r); int m = (l+r)/2; update(idx*2, l, m, ql, qr, setOp, A_val, B_val); update(idx*2+1, m+1, r, ql, qr, setOp, A_val, B_val); } ll query(int idx, int l, int r, int pos) { if(l == r){ if(lazySet[idx]) return lazySetA[idx] + lazySetB[idx]*l; return base[l-1] + lazyAddA[idx] + lazyAddB[idx]*l; } pushDown(idx, l, r); int m = (l+r)/2; if(pos <= m) return query(idx*2, l, m, pos); else return query(idx*2+1, m+1, r, pos); } }; struct Node { int l, r; int leftVal, rightVal; int pre, suf, ans; bool allSame; }; struct SegD { int n; vector<Node> tree; vector<bool> lazySet; vector<int> lazySetVal, lazyAdd; SegD(const vector<int>& arr) { n = arr.size(); tree.resize(4*n); lazySet.assign(4*n, false); lazySetVal.assign(4*n, 0); lazyAdd.assign(4*n, 0); build(1, 1, n, arr); } Node combine(const Node &L, const Node &R) { if(L.ans == 0) return R; if(R.ans == 0) return L; Node res; res.l = L.l; res.r = R.r; res.leftVal = L.leftVal; res.rightVal = R.rightVal; res.allSame = (L.allSame && R.allSame && (L.rightVal == R.leftVal)); if(L.allSame && L.leftVal == R.leftVal) res.pre = L.ans + R.pre; else res.pre = L.pre; if(R.allSame && R.rightVal == L.rightVal) res.suf = R.ans + L.suf; else res.suf = R.suf; res.ans = max({L.ans, R.ans, L.suf + R.pre}); return res; } void build(int idx, int l, int r, const vector<int>& arr) { tree[idx].l = l; tree[idx].r = r; if(l == r) { tree[idx].leftVal = tree[idx].rightVal = arr[l-1]; tree[idx].pre = tree[idx].suf = tree[idx].ans = 1; tree[idx].allSame = true; return; } int m = (l+r)/2; build(idx*2, l, m, arr); build(idx*2+1, m+1, r, arr); tree[idx] = combine(tree[idx*2], tree[idx*2+1]); } void applySet(int idx, int l, int r, int val) { tree[idx].leftVal = tree[idx].rightVal = val; tree[idx].pre = tree[idx].suf = tree[idx].ans = (r - l + 1); tree[idx].allSame = true; lazySet[idx] = true; lazySetVal[idx] = val; lazyAdd[idx] = 0; } void applyAdd(int idx, int l, int r, int addVal) { tree[idx].leftVal += addVal; tree[idx].rightVal += addVal; if(lazySet[idx]) lazySetVal[idx] += addVal; else lazyAdd[idx] += addVal; } void pushDown(int idx) { int l = tree[idx].l, r = tree[idx].r, m = (l+r)/2; int lc = idx*2, rc = idx*2+1; if(lazySet[idx]) { applySet(lc, l, m, lazySetVal[idx]); applySet(rc, m+1, r, lazySetVal[idx]); lazySet[idx] = false; lazySetVal[idx] = 0; } if(lazyAdd[idx] != 0) { applyAdd(lc, l, m, lazyAdd[idx]); applyAdd(rc, m+1, r, lazyAdd[idx]); lazyAdd[idx] = 0; } } void updateSet(int idx, int ql, int qr, int val) { int l = tree[idx].l, r = tree[idx].r; if(ql > r || qr < l) return; if(ql <= l && r <= qr) { applySet(idx, l, r, val); return; } pushDown(idx); updateSet(idx*2, ql, qr, val); updateSet(idx*2+1, ql, qr, val); tree[idx] = combine(tree[idx*2], tree[idx*2+1]); } void updateAdd(int idx, int ql, int qr, int addVal) { int l = tree[idx].l, r = tree[idx].r; if(ql > r || qr < l) return; if(ql <= l && r <= qr) { applyAdd(idx, l, r, addVal); return; } pushDown(idx); updateAdd(idx*2, ql, qr, addVal); updateAdd(idx*2+1, ql, qr, addVal); tree[idx] = combine(tree[idx*2], tree[idx*2+1]); } Node query(int idx, int ql, int qr) { int l = tree[idx].l, r = tree[idx].r; if(ql > r || qr < l) return {0,0,0,0,0,true}; if(ql <= l && r <= qr) return tree[idx]; pushDown(idx); Node L = query(idx*2, ql, qr); Node R = query(idx*2+1, ql, qr); if(L.ans == 0) return R; if(R.ans == 0) return L; return combine(L, R); } }; int32_t main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; vector<ll> A(n); for (int i = 0; i < n; i++) cin >> A[i]; vector<int> D; if(n > 1){ D.resize(n-1); for (int i = 0; i < n-1; i++) D[i] = A[i+1] - A[i]; } SegA segA(n, A); SegD segD(n > 1 ? D : vector<int>()); while(q--){ int t; cin >> t; if(t == 1){ int L, R; ll S, C; cin >> L >> R >> S >> C; // Update A with patch: add f(i)=S+(i-L)*C for i in [L,R] ll addA = S - C * L, addB = C; segA.update(1, 1, n, L, R, false, addA, addB); // Update D: if(n > 1){ if(L > 1){ segD.updateAdd(1, L-1, L-1, S); } if(R < n){ segD.updateAdd(1, R, R, - (S + (R - L) * C)); } if(L <= R-1){ segD.updateAdd(1, L, R-1, C); } } } else if(t == 2){ int L, R; ll S, C; cin >> L >> R >> S >> C; // Rewrite A: set A[i] = S + (i-L)*C for i in [L,R] ll setA = S - C * L, setB = C; segA.update(1, 1, n, L, R, true, setA, setB); if(n > 1){ if(L > 1){ ll prev = segA.query(1, 1, n, L-1); int newD = (int)( (S) - prev ); segD.updateSet(1, L-1, L-1, newD); } if(R < n){ ll nxt = segA.query(1, 1, n, R+1); int newD = (int)( nxt - (S + (R - L)*C) ); segD.updateSet(1, R, R, newD); } if(L <= R-1){ segD.updateSet(1, L, R-1, (int)C); } } } else { int L, R; cin >> L >> R; if(L == R) cout << 1 << "\n"; else { Node res = segD.query(1, L, R-1); cout << res.ans + 1 << "\n"; } } } return 0; }
#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...