Submission #633225

#TimeUsernameProblemLanguageResultExecution timeMemory
633225Gromp15Abracadabra (CEOI22_abracadabra)C++17
100 / 100
530 ms40216 KiB
#include <bits/stdc++.h> #define ll long long #define ar array using namespace std; struct fenwick { int n, lg; vector<int> bit; fenwick(int a) : n(a), lg(__lg(n)), bit(a+1) {} int pref(int pos) { pos++; int ret = 0; if (pos > n) pos = n; while (pos) { ret += bit[pos], pos -= pos&-pos; } return ret; } int point(int pos) { return pref(pos) - pref(pos-1); } void update(int pos, int x) { pos++; while (pos <= n) { bit[pos] += x, pos += pos&-pos; } } int last_smaller(int x) { int pos = 0; for (int i = lg; i >= 0; i--) { if (pos + (1 << i) <= n && x > bit[pos+(1<<i)]) { x -= bit[pos+(1<<i)]; pos += 1<<i; } } return pos-1; } }; int main() { cin.tie(0)->sync_with_stdio(0); int a, q; cin >> a >> q; vector<int> t(a); for (int &x : t) cin >> x; auto upd = [&](vector<int> &C) { vector<int> A(a/2), B(a/2), ret(a); for (int j = 0; j < a/2; j++) A[j] = C[j], B[j] = C[j+a/2]; int ii = 0, jj = 0; for (int j = 0; j < a; j++) { if (ii == a/2) ret[j] = B[jj++]; else if (jj == a/2) ret[j] = A[ii++]; else { if (A[ii] < B[jj]) ret[j] = A[ii++]; else ret[j] = B[jj++]; } } swap(C, ret); }; vector<int> orig_t(t); upd(t); vector<int> where(a+1); fenwick fw(a+1); for (int i = 0; i < a; i++) where[t[i]] = i; for (int i = 0; i < a; i++) { int r = i; while (r + 1 < a && t[r+1] <= t[i]) r++; fw.update(t[i], r-i+1); i = r; } vector<int> nxt(a, a); stack<ar<int, 2>> stk; for (int i = a-1; i >= 0; i--) { while (stk.size() && stk.top()[0] < t[i]) stk.pop(); if (stk.size()) nxt[i] = stk.top()[1]; stk.push({t[i], i}); } vector<ar<int, 3>> queries(q); for (int i = 0; i < q; i++) { cin >> queries[i][0] >> queries[i][1]; queries[i][2] = i; } sort(queries.begin(), queries.end()); vector<int> ret(q); int time = 1; bool converged = 0; for (int i = 0; i < q; i++) { while (!converged && time < queries[i][0]) { int ans = fw.last_smaller(a/2) + 1; if (fw.pref(ans) == a/2) { converged = 1; break; } int l1 = where[ans] + a/2 - fw.pref(ans-1), r1 = where[ans] + fw.point(ans) - 1; int old_idx = fw.pref(ans-1), old_len = fw.point(ans); fw.update(ans, -old_len + a/2 - old_idx); while (l1 <= r1) { int nxt_ = min(r1, nxt[l1] - 1); //assert(fw.point(t[l1]) == 0); fw.update(t[l1], nxt_-l1+1); l1 = nxt_ + 1; } time++; } if (!queries[i][0]) ret[queries[i][2]] = orig_t[queries[i][1]-1]; else { int idx = queries[i][1], ans = fw.last_smaller(idx) + 1; ret[queries[i][2]] = t[where[ans] + idx - fw.pref(ans-1) - 1]; } } for (int i = 0; i < q; i++) cout << ret[i] << '\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...