제출 #1298761

#제출 시각아이디문제언어결과실행 시간메모리
1298761ThunnusProgression (NOI20_progression)C++20
0 / 100
615 ms1114112 KiB
#include<bits/stdc++.h> #pragma GCC optimize("unroll-loops,O3") using namespace std; using i64 = long long; //#define int i64 #define vi vector<int> #define vvi vector<vi> #define vb vector<bool> #define se second #define fi first #define pii pair<int, int> #define sz(x) (int)(x).size() struct ASegTree{ struct Node{ i64 sum; int mult; i64 lazysum = 0, lazymult = 0; bool set0 = false; Node(i64 sm, int mul, i64 lzs, i64 lzm, bool b) : sum(sm), mult(mul), lazysum(lzs), lazymult(lzm), set0(b) {} Node() : Node(0, 0, 0, 0, false) {} }; int n; vector<Node> st; ASegTree(int n) : n(n), st(4 * n) {} inline void apply(int v, int sm, int ml, bool set0){ if(set0){ st[v].sum = 0; st[v].lazysum = 0; st[v].lazymult = 0; st[v].set0 = true; return; } st[v].sum += sm; st[v].lazysum += sm; st[v].sum += st[v].mult * ml; st[v].lazymult += ml; return; } inline void propagate(int v){ if(st[v].set0){ apply(2 * v, 0, 0, true); apply(2 * v + 1, 0, 0, true); } apply(2 * v, st[v].lazysum, st[v].lazymult, false); apply(2 * v + 1, st[v].lazysum, st[v].lazymult, false); st[v].lazysum = st[v].lazymult = 0; st[v].set0 = false; return; } inline void build(int v, int tl, int tr, const vi &a){ if(tl == tr){ st[v] = {a[tl - 1], tl - 1, 0, 0, false}; return; } int mid = (tl + tr) / 2; build(2 * v, tl, mid, a); build(2 * v + 1, mid + 1, tr, a); st[v].sum = st[2 * v].sum + st[2 * v + 1].sum; return; } inline void build(const vi &a){ build(1, 1, n, a); } inline void update(int ul, int ur, int sm, int ml, bool set0, int v, int tl, int tr){ if(ul > tr || tl > ur) return; if(ul <= tl && tr <= ur){ apply(v, sm, ml, set0); return; } int mid = (tl + tr) / 2; propagate(v); update(ul, ur, sm, ml, set0, 2 * v, tl, mid); update(ul, ur, sm, ml, set0, 2 * v + 1, mid + 1, tr); st[v].sum = st[2 * v].sum + st[2 * v + 1].sum; return; } inline void update(int ul, int ur, int sm, int ml, bool set0){ update(ul + 1, ur + 1, sm, ml, set0, 1, 1, n); } inline i64 query(int pos, int v, int tl, int tr){ if(tl == tr){ return st[v].sum; } int mid = (tl + tr) / 2; propagate(v); if(pos <= mid){ return query(pos, 2 * v, tl, mid); } else{ return query(pos, 2 * v + 1, mid + 1, tr); } } inline i64 query(int pos){ return query(pos + 1, 1, 1, n); } }; struct DSegTree{ struct Node{ i64 pval, sval; int pf, sf, sub; i64 lazyadd = 0; int len; bool set0 = false; Node(i64 pv, i64 sv, int pf, int sf, int sub, i64 lza, int len, bool set0) : pval(pv), sval(sv), pf(pf), sf(sf), sub(sub), lazyadd(lza), len(len), set0(set0) {} Node() : Node(0, 0, 0, 0, 0, 0, 0, false) {} }; int n; vector<Node> st; DSegTree(int n) : n(n), st(4 * n) {} inline Node combine(const Node &a, const Node &b){ Node c; c.len = a.len + b.len; c.pval = a.pval, c.sval = b.sval; c.pf = a.pf; if(a.len == a.pf && a.sval == b.pval){ c.pf = a.len + b.pf; } c.sf = b.sf; if(b.len == b.sf && a.sval == b.pval){ c.sf = b.len + a.sf; } c.sub = max({c.sf, c.pf, a.sub, b.sub}); if(a.sval == b.pval){ c.sub = max(c.sub, a.sf + b.pf); } return c; } inline void apply(int v, int addval, bool set0){ if(set0){ st[v].pval = st[v].sval = st[v].lazyadd = 0; st[v].pf = st[v].sf = st[v].sub = st[v].len; st[v].set0 = true; return; } st[v].pval += addval, st[v].sval += addval, st[v].lazyadd += addval; return; } inline void propagate(int v){ if(st[v].set0){ apply(2 * v, 0, true); apply(2 * v + 1, 0, true); } apply(2 * v, st[v].lazyadd, false); apply(2 * v + 1, st[v].lazyadd, false); st[v].lazyadd = 0; st[v].set0 = false; return; } inline void build(int v, int tl, int tr, const vi &a){ if(tl == tr){ st[v] = {a[tl - 1], a[tl - 1], 1, 1, 1, 0, 1, false}; return; } int mid = (tl + tr) / 2; build(2 * v, tl, mid, a); build(2 * v + 1, mid + 1, tr, a); st[v] = combine(st[2 * v], st[2 * v + 1]); return; } inline void build(const vi &a){ build(1, 1, n, a); } inline void update(int ul, int ur, int add, bool set0, int v, int tl, int tr){ if(ul > tr || tl > ur) return; if(ul <= tl && tr <= ur){ apply(v, add, set0); return; } int mid = (tl + tr) / 2; propagate(v); update(ul, ur, add, set0, 2 * v, tl, mid); update(ul, ur, add, set0, 2 * v + 1, mid + 1, tr); st[v] = combine(st[2 * v], st[2 * v + 1]); return; } inline void update(int ul, int ur, int add, bool set0){ update(ul + 1, ur + 1, add, set0, 1, 1, n); } inline Node query(int ql, int qr, int v, int tl, int tr){ if(ql > tr || tl > qr) return Node(); if(ql <= tl && tr <= qr) return st[v]; int mid = (tl + tr) / 2; propagate(v); return combine(query(ql, qr, 2 * v, tl, mid), query(ql, qr, 2 * v + 1, mid + 1, tr)); } inline int query(int ql, int qr){ return query(ql + 1, qr + 1, 1, 1, n).sub; } }; inline void solve(){ int n, q; cin >> n >> q; vi a(n), d(n - 1); for(int i = 0; i < n; i++){ cin >> a[i]; if(i){ d[i - 1] = a[i] - a[i - 1]; } } ASegTree aseg(n); aseg.build(a); DSegTree dseg(n - 1); dseg.build(d); auto patch = [&](int l, int r, int s, int c) -> void { aseg.update(l, r, s - l * c, c, false); if(l){ dseg.update(l - 1, l - 1, s, false); } if(l < r){ dseg.update(l, r - 1, c, false); } if(r + 1 < n){ dseg.update(r, r, -s - (r - l) * c, false); } return; }; auto rewrite = [&](int l, int r, int s, int c) -> void { aseg.update(l, r, 0, 0, true); aseg.update(l, r, s - l * c, c, false); if(l){ i64 befa = aseg.query(l - 1); dseg.update(l - 1, l - 1, 0, true); dseg.update(l - 1, l - 1, s - befa, false); } if(l < r){ dseg.update(l, r - 1, 0, true); dseg.update(l, r - 1, c, false); } if(r + 1 < n){ i64 afa = aseg.query(r + 1); dseg.update(r, r, 0, true); dseg.update(r, r, s + (r - l) * c - afa, false); } return; }; auto evaluate = [&](int l, int r) -> int { int ans = 0; if(l < r){ ans = max(ans, dseg.query(l, r - 1)); //cout << "l: " << l << " r: " << r << " dseg: " << dseg.query(l, r - 1) << "\n"; } return ans + 1; }; while(q--){ int type, l, r; cin >> type >> l >> r; l--, r--; if(type == 1){ int s, c; cin >> s >> c; patch(l, r, s, c); } else if(type == 2){ int s, c; cin >> s >> c; rewrite(l, r, s, c); } else{ cout << evaluate(l, r) << "\n"; } } return; } signed main(){ ios_base::sync_with_stdio(false); cin.tie(0); int t = 1; //cin >> t; while(t--){ solve(); } 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...