Submission #685635

#TimeUsernameProblemLanguageResultExecution timeMemory
685635cig32The short shank; Redemption (BOI21_prison)C++17
80 / 100
2090 ms143340 KiB
#pragma GCC optimize("Ofast") #include "bits/stdc++.h" using namespace std; const int MAXN = 2e5 + 10; const int MOD = 1e9 + 7; mt19937_64 rng((int)std::chrono::steady_clock::now().time_since_epoch().count()); int rnd(int x, int y) { int u = uniform_int_distribution<int>(x, y)(rng); return u; } int bm(int b, int p) { if(p==0) return 1 % MOD; int r = bm(b, p >> 1); if(p&1) return (((r*r) % MOD) * b) % MOD; return (r*r) % MOD; } int inv(int b) { return bm(b, MOD-2); } int fastlog(int x) { return (x == 0 ? -1 : 64 - __builtin_clzll(x) - 1); } void printcase(int i) { cout << "Case #" << i << ": "; } struct node { int ma = 0, upd = 0, idx; } st[8000010]; void push_up(int idx) { st[idx].ma = max(st[2*idx+1].ma, st[2*idx+2].ma); st[idx].idx = (st[2*idx+1].ma == st[idx].ma ? st[2*idx+1].idx : st[2*idx+2].idx); } void build(int l, int r, int idx) { if(l == r) { st[idx].idx = l; return; } int mid = (l + r) >> 1; build(l, mid, 2*idx+1); build(mid+1, r, 2*idx+2); push_up(idx); } void push_down(int idx) { st[2*idx+1].ma += st[idx].upd; st[2*idx+1].upd += st[idx].upd; st[2*idx+2].ma += st[idx].upd; st[2*idx+2].upd += st[idx].upd; st[idx].upd = 0; } void u(int l, int r, int constl, int constr, int idx, int val) { if(l <= constl && constr <= r) { st[idx].ma += val; st[idx].upd += val; return; } int mid = (constl + constr) >> 1; push_down(idx); if(mid < l || r < constl) u(l, r, mid+1, constr, 2*idx+2, val); else if(constr < l || r < mid+1) u(l, r, constl, mid, 2*idx+1, val); else { u(l, r, constl, mid, 2*idx+1,val); u(l, r, mid+1, constr, 2*idx+2, val); } push_up(idx); } pair<int, int> qu(int l, int r, int constl, int constr, int idx) { if(l <= constl && constr <= r) return {st[idx].ma, st[idx].idx}; int mid = (constl + constr) >> 1; push_down(idx); if(mid < l || r < constl) return qu(l, r, mid+1, constr, 2*idx+2); else if(constr < l || r < mid+1) return qu(l, r, constl, mid, 2*idx+1); else { return max(qu(l, r, constl, mid, 2*idx+1), qu(l, r, mid+1, constr, 2*idx+2)); } } int seg[8000010]; void u2(int l, int r, int tar, int idx, int val) { if(l == r) { seg[idx] = val; return; } int mid = (l + r) >> 1; if(tar <= mid) u2(l, mid, tar, 2*idx+1, val); else u2(mid+1, r, tar, 2*idx+2, val); seg[idx] = min(seg[2*idx+1], seg[2*idx+2]); } int qu2(int l, int r, int constl, int constr, int idx, int val) { // first <= v if(l <= constl && constr <= r) { if(seg[idx] > val) return -1; while(constl < constr) { int mid = (constl + constr) >> 1; if(seg[2*idx+1] <= val) constr = mid, idx = 2*idx+1; else constl = mid+1, idx = 2*idx+2; } return constl; } int mid = (constl + constr) >> 1; if(mid < l || r < constl) return qu2(l, r, mid+1, constr, 2*idx+2, val); else if(constr < l || r < mid+1) return qu2(l, r, constl, mid, 2*idx+1, val); else { int lc = qu2(l, r, constl, mid, 2*idx+1, val); if(lc != -1) return lc; return qu2(l, r, mid+1, constr, 2*idx+2, val); } } int qu3(int l, int r, int constl, int constr, int idx, int val) { // last <= v if(l <= constl && constr <= r) { if(seg[idx] > val) return -1; while(constl < constr) { int mid = (constl + constr) >> 1; if(seg[2*idx+2] <= val) constl = mid+1, idx = 2*idx+2; else constr = mid, idx = 2*idx+1; } return constl; } int mid = (constl + constr) >> 1; if(mid < l || r < constl) return qu3(l, r, mid+1, constr, 2*idx+2, val); else if(constr < l || r < mid+1) return qu3(l, r, constl, mid, 2*idx+1, val); else { int rc = qu3(l, r, mid+1, constr, 2*idx+2, val); if(rc != -1) return rc; return qu3(l, r, constl, mid, 2*idx+1, val); } } int32_t main() { ios::sync_with_stdio(0); cin.tie(0); int n, d, t; cin >> n >> d >> t; int a[n+1]; for(int i=1; i<=n; i++) cin >> a[i]; for(int i=1; i<=n; i++) u2(1, n, i, 0, a[i]-i); // stb.range_add(i, i, a[i]-i); build(1, n, 0); int ans = 0; int save[n+1]; for(int i=1; i<=n; i++) { int bruh = qu3(1, i, 1, n, 0, t-i); //stb.query_lastAtMost(1, i, t-i); save[i] = bruh; } for(int i=1; i<=n; i++) { int bruh = save[i]; if(bruh != -1) { ans++; if(bruh < i) { u(bruh, i-1, 1, n, 0, 1); } u2(1, n, i, 0, bruh); //stb.range_assign(i, i, bruh); } else { u2(1, n, i, 0, MOD); //stb.range_assign(i, i, MOD); } } for(int it=0; it<d; it++) { int ss = qu(1, n-1, 1, n, 0).second; int savee = ans; while(1) { int idx = qu2(ss+1, n, 1, n, 0, ss); //stb.query_firstAtMost(ss+1, n, ss); if(idx == -1) break; u2(1, n, idx, 0, MOD); //stb.range_assign(idx, idx, MOD); u(save[idx], idx-1, 1, n, 0, -1); ans--; } if(savee == ans) break; } cout << ans << "\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...