Submission #786765

#TimeUsernameProblemLanguageResultExecution timeMemory
786765qwerasdfzxclWeirdtree (RMI21_weirdtree)C++17
100 / 100
566 ms29608 KiB
#include "weirdtree.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; constexpr int INF = 1e9 + 100; int n; struct Node{ int mx, smx, cnt; Node(){} Node(int x):mx(x), smx(0), cnt(1) {} Node(int _mx, int _smx, int _cnt): mx(_mx), smx(_smx), cnt(_cnt){} Node operator + (const Node &N) const{ Node ret; if (mx > N.mx) ret.mx = mx, ret.smx = max(N.mx, smx), ret.cnt = cnt; else if (mx < N.mx) ret.mx = N.mx, ret.smx = max(mx, N.smx), ret.cnt = N.cnt; else ret.mx = mx, ret.smx = max(smx, N.smx), ret.cnt = cnt + N.cnt; return ret; } }; struct Seg{ Node tree[1201200]; ll tree2[1201200]; int lazy[1201200]; void init(int i, int l, int r, int a[]){ lazy[i] = INF; if (l==r){ tree[i] = Node(a[l]); tree2[i] = a[l]; return; } int m = (l+r)>>1; init(i<<1, l, m, a); init(i<<1|1, m+1, r, a); tree[i] = tree[i<<1] + tree[i<<1|1]; tree2[i] = tree2[i<<1] + tree2[i<<1|1]; } void propagate(int i, int l, int r){ if (lazy[i]==INF) return; int d = tree[i].mx - min(tree[i].mx, lazy[i]); tree2[i] -= (ll)d * tree[i].cnt; tree[i].mx = min(tree[i].mx, lazy[i]); assert(tree[i].mx > tree[i].smx || tree[i].mx==0); if (l!=r){ lazy[i<<1] = min(lazy[i<<1], lazy[i]); lazy[i<<1|1] = min(lazy[i<<1|1], lazy[i]); } lazy[i] = INF; } void updateM(int i, int l, int r, int s, int e, int x){ propagate(i, l, r); if (r<s || e<l) return; if (s<=l && r<=e && (x > tree[i].smx || (x==0 && tree[i].smx==0))){ lazy[i] = x; propagate(i, l, r); return; } int m = (l+r)>>1; updateM(i<<1, l, m, s, e, x); updateM(i<<1|1, m+1, r, s, e, x); tree[i] = tree[i<<1] + tree[i<<1|1]; tree2[i] = tree2[i<<1] + tree2[i<<1|1]; } void updateV(int i, int l, int r, int p, int x){ propagate(i, l, r); if (r<p || p<l) return; if (l==r){ tree[i] = Node(x); tree2[i] = x; return; } int m = (l+r)>>1; updateV(i<<1, l, m, p, x); updateV(i<<1|1, m+1, r, p, x); tree[i] = tree[i<<1] + tree[i<<1|1]; tree2[i] = tree2[i<<1] + tree2[i<<1|1]; } int prefix(int i, int l, int r, int s, int val, int cnt){ // printf(" call %d %d %d %d %d %d\n", i, l, r, s, val, cnt); propagate(i, l, r); if (r<s) return 0; if (s<=l){ if (tree[i].mx < val) return 0; if (tree[i].mx==val && tree[i].cnt < cnt) return -tree[i].cnt; if (l==r){ if (tree[i].mx == val) return l; else return 0; } } int m = (l+r)>>1; int ret1 = prefix(i<<1, l, m, s, val, cnt); if (ret1 > 0) return ret1; cnt += ret1; int ret2 = prefix(i<<1|1, m+1, r, s, val, cnt); if (ret2 > 0) return ret2; return ret1 + ret2; } Node query(int i, int l, int r, int s, int e){ propagate(i, l, r); if (r<s || e<l) return Node(0, 0, 0); if (s<=l && r<=e) return tree[i]; int m = (l+r)>>1; return query(i<<1, l, m, s, e) + query(i<<1|1, m+1, r, s, e); } ll sum(int i, int l, int r, int s, int e){ propagate(i, l, r); if (r<s || e<l) return 0; if (s<=l && r<=e) return tree2[i]; int m = (l+r)>>1; return sum(i<<1, l, m, s, e) + sum(i<<1|1, m+1, r, s, e); } }tree; void initialise(int N, int Q, int h[]) { n = N; tree.init(1, 1, n, h); } void cut(int l, int r, int k) { while(k > 0){ auto N = tree.query(1, 1, n, l, r); // printf("ok %d %d cnt = %d / k = %d\n", N.mx, N.smx, N.cnt, k); if (k >= (ll)N.cnt * (N.mx - N.smx)){ k -= (ll)N.cnt * (N.mx - N.smx); tree.updateM(1, 1, n, l, r, N.smx); if (N.smx==0) return; } else{ int quo = k / N.cnt, rem = k % N.cnt; int idx = l-1; if (rem > 0) idx = tree.prefix(1, 1, n, l, N.mx, rem); // printf(" okok idx = %d\n", idx); if (l<=idx) tree.updateM(1, 1, n, l, idx, N.mx-quo-1); if (idx+1<=r) tree.updateM(1, 1, n, idx+1, r, N.mx-quo); return; } } } void magic(int i, int x) { tree.updateV(1, 1, n, i, x); } long long int inspect(int l, int r) { return tree.sum(1, 1, n, l, r); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...