From e88ec279a0b44c1a77c4b5e0d9665f1189491f3c Mon Sep 17 00:00:00 2001 From: Segcolt <9hmbzr275@mozmail.com> Date: Wed, 25 Sep 2024 17:52:28 -0300 Subject: [PATCH] Finally finish the problem This was tough... Hopefully it mean I got better too. --- 2015/phase2/fila.cpp | 127 ++++++++++++++++++++++--------------------- 1 file changed, 66 insertions(+), 61 deletions(-) diff --git a/2015/phase2/fila.cpp b/2015/phase2/fila.cpp index 7e0332f..c7a0adb 100644 --- a/2015/phase2/fila.cpp +++ b/2015/phase2/fila.cpp @@ -69,19 +69,14 @@ auto operator>>(istream &is, vector> &vec)->istream& { return is; } +#define int ll + struct insertion { int pos; int val; insertion(int pos, int val): pos(pos), val(val) {} - - // bool operator<(insertion &i) { - // if (pos == i.pos) { - // return pos == 0 ? ind < i.pos : pos > i.pos; - // } - // return ind < i.ind; - // } }; struct query { @@ -113,23 +108,41 @@ ll search(int n, int l, int r, int lim, int v) return ans ?: search(n * 2, l, mid, lim, v); } -void add(int i) +void add(int i, int v = 1) { for (; i < bit.size(); i += (i & -i)) { - bit[i]++; + bit[i] += v; } } -ll get(int i) +ll get(int v) { ll ans = 0; - for (; i >= 1; i -= (i & -i)) { + for (int i = 31; i >= 0; i--) { + ll tmp = (1 << i) + ans; + if (tmp >= bit.size()) { + continue; + } + + if (bit[tmp] <= v) { + v -= bit[tmp]; + ans = tmp; + } + } + if (v == 0) return ans; + return -1; +} + +ll sum(int i) +{ + ll ans = 0; + for (; i > 0; i -= i & -i) { ans += bit[i]; } return ans; } -int main() +signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); @@ -137,80 +150,72 @@ int main() int n; cin >> n; vl queue(n); - cin >> queue; + V inserts; + // cin >> queue; + rep(i, n) { + int val; + cin >> val; + inserts.emplace_back(i, val); + } int q; cin >> q; + V queries(q + n); + for (size_t i = 0; i < inserts.size(); i++) { + queries[i] = query(0, inserts[i].pos, inserts[i].val); + } - V queries(q); - V inserts; + size_t num = inserts.size(); - rep(i, q) { + nrep(i, n, n + q) { int type, pos; ll value; cin >> type >> pos >> value; queries[i] = query(type, pos, value); if (type == 0) { - inserts.emplace_back(pos, value); + num++; } } - reverse(queries.begin(), queries.end()); - reverse(inserts.begin(), inserts.end()); - - vl act(n + inserts.size(), -1); - bit.assign(n + inserts.size() + 1, 0); - for (auto [p, v] : inserts) { - + vl act(num, -1); + bit.assign(queries.size() + 1, 0); + for (size_t i = 1; i <= queries.size(); i++) { + add(i); } - // size_t now = 0; - // for (size_t i = 0; i < act.size(); i++) { - // if (act[i] == -1) { - // act[i] = queue[now]; - // now++; - // } - // } - size_t bef = act.size(); - while (__builtin_popcount(act.size()) != 1) { + for (auto itr = queries.rbegin(); itr != queries.rend(); itr++) { + auto &[t, p, v] = *itr; + + if (t == 0) { + p = get(p) + 1; + + add(p, -1); + continue; + } + p = get(p - 1) + 1; + } + + while (act.size() != 0 && __builtin_popcount(act.size()) != 1) { act.push_back(-1); } - size_t actn = act.size(); - cout << act; - segtree.resize(act.size() * 2); - bit.resize(act.size() + 1); + segtree.assign(act.size() * 2, -1); + bit.assign(act.size() + 1, 0); - for (size_t i = actn; i < actn * 2; i++) { - segtree[i] = act[i - actn]; - } - for (size_t i = actn - 1; i > 0; i--) { - segtree[i] = max(segtree[i * 2], segtree[i * 2 + 1]); - } - - vl ans(queries.size() - inserts.size()); - auto itr = ans.rbegin(); for (auto [type, pos, value] : queries) { + // cerr << bit; if (type == 0) { - int fix = get(pos + 1); - // cout << "Remove fix: " << fix << '\n'; - segtree[pos + actn + fix] = -1; - add(pos + fix + 1); - for (size_t i = (pos + actn + fix) / 2; i >= 1; i /= 2) { + add(pos); + + act[pos - 1] = value; + segtree[act.size() + pos - 1] = value; + for (size_t i = (act.size() + pos - 1) / 2; i > 0; i /= 2) { segtree[i] = max(segtree[i * 2], segtree[i * 2 + 1]); } continue; } - int fix = get(pos); - // cout << "Query fix: " << fix << '\n'; - int ans = search(1, 1, bef, pos + fix, act[pos + fix - 1] + value); - // cout << "Found: " << ans << " with: " << act[pos + fix - 1] << '\n'; - *itr = ans ? ans - get(ans) : 0; - itr++; - } - - for (auto i : ans) { - cout << i << '\n'; + int ans = search(1, 1, act.size(), pos, act[pos - 1] + value); + cout << sum(ans) << '\n'; } }