Submission #1219227

#TimeUsernameProblemLanguageResultExecution timeMemory
1219227nutellaWeirdtree (RMI21_weirdtree)C++20
100 / 100
341 ms32740 KiB
#include "weirdtree.h" #include <bits/stdc++.h> using namespace std; using ll = long long; constexpr int infi = 1e9 + 7; struct Info { ll sum = 0; int mx[2]{-infi, -infi}, cnt[2]{}; Info() = default; Info(int x) { mx[0] = x; mx[1] = -1e9; cnt[0] = 1; sum = x; } }; Info operator+(const Info &l, const Info &r) { Info res{}; res.sum = l.sum + r.sum; res.mx[0] = max(l.mx[0], r.mx[0]); if (l.mx[0] == res.mx[0]) { res.cnt[0] += l.cnt[0]; res.cnt[1] += l.cnt[1]; res.mx[1] = l.mx[1]; } else { res.cnt[1] += l.cnt[0] + l.cnt[1]; res.mx[1] = l.mx[0]; } if (r.mx[0] == res.mx[0]) { res.cnt[0] += r.cnt[0]; res.cnt[1] += r.cnt[1]; res.mx[1] = max(res.mx[1], r.mx[1]); } else { res.cnt[1] += r.cnt[0] + r.cnt[1]; res.mx[1] = max(res.mx[1], r.mx[0]); } return res; } vector<Info> t; vector<int> tag; // fill tag with 1e9+7 int sz = 1; void tapply(int x, int tg) { if (t[x].mx[0] > tg) { t[x].sum -= t[x].cnt[0] * 1LL * (t[x].mx[0] - tg); t[x].mx[0] = tg; // SEE: WE DECREASE HERE! assert(t[x].mx[0] > t[x].mx[1]); tag[x] = tg; } } void tpush(int x) { if (tag[x] != infi) { for (int ch : {x * 2, x * 2 + 1}) { tapply(ch, tag[x]); } tag[x] = infi; } } void tpull(int x) { t[x] = t[x << 1] + t[x << 1 | 1]; } void rangeSetMin(int l, int r, int m, int x = 1, int lx = 0, int rx = sz) { // a[i] min= m if (l >= rx || lx >= r || t[x].mx[0] <= m) { return; } if (l <= lx && rx <= r && t[x].mx[1] < m) { return tapply(x, m); } int mid = lx + rx >> 1; tpush(x); rangeSetMin(l, r, m, x << 1, lx, mid); rangeSetMin(l, r, m, x << 1 | 1, mid, rx); tpull(x); } int findKthMax(int l, int r, int &k, int m, int x = 1, int lx = 0, int rx = sz) { // inclusive if (l >= rx || lx >= r || t[x].mx[0] < m) { return -1; } if (l <= lx && rx <= r && t[x].cnt[0] < k) { k -= t[x].cnt[0]; return -1; } if (lx + 1 == rx) { return lx; } tpush(x); int mid = lx + rx >> 1; int res = findKthMax(l, r, k, m, x << 1, lx, mid); if (res == -1){ res = findKthMax(l, r, k, m, x << 1 | 1, mid, rx); } return res; } Info rangeSum(int l, int r, int x = 1, int lx = 0, int rx = sz) { if (l >= rx || lx >= r) { return {}; } if (l <= lx && rx <= r) { return t[x]; } int mid = lx + rx >> 1; tpush(x); return rangeSum(l, r, x << 1, lx, mid) + rangeSum(l, r, x << 1 | 1, mid, rx); } void modify(int i, int val, int x = 1, int lx = 0, int rx = sz) { if (lx + 1 == rx) { t[x] = Info(val); return; } int mid = lx + rx >> 1; tpush(x); if (i < mid) { modify(i, val, x << 1, lx, mid); } else { modify(i, val, x << 1 | 1, mid, rx); } tpull(x); } void initialise(int N, int Q, int h[]) { sz = 1 << __lg(N) + !!(N & (N - 1)); tag.assign(sz << 1, infi); t.assign(sz << 1, {}); for (int i = 0; i < N; ++i) { t[i + sz] = Info(h[i + 1]); } for (int i = sz - 1; i > 0; --i) { tpull(i); } // for (int i = 1; i < t.size(); ++i) { // cout << t[i].sum << " "; // } // cout << endl; // cerr << rangeSum(0, N).sum << endl; } void cut(int l, int r, int k) { --l; while (k > 0) { auto info = rangeSum(l, r); if (info.sum <= k) { rangeSetMin(l, r, 0); break; } if ((info.mx[0] - info.mx[1]) * 1LL * (info.cnt[0]) >= k) { int full = k / info.cnt[0]; rangeSetMin(l, r, info.mx[0] - full); k -= full * info.cnt[0]; if (k > 0) { int p = findKthMax(l, r, k, info.mx[0] - full); rangeSetMin(l, p + 1, info.mx[0] - full - 1); } break; } int d = (info.mx[0] - info.mx[1]) * 1LL * (info.cnt[0]); k -= d; rangeSetMin(l, r, info.mx[1]); } // Your code here. } void magic(int i, int x) { --i; modify(i, x); // Your code here. } ll inspect(int l, int r) { --l; return rangeSum(l, r).sum; }
#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...