Submission #793262

#TimeUsernameProblemLanguageResultExecution timeMemory
793262enerelt14Abracadabra (CEOI22_abracadabra)C++14
100 / 100
718 ms52752 KiB
#include <algorithm> #include <array> #include <bitset> #include <cassert> #include <chrono> #include <climits> #include <cmath> #include <complex> #include <cstring> #include <functional> #include <iomanip> #include <iostream> #include <map> #include <numeric> #include <queue> #include <random> #include <set> #include <vector> #include <stack> #define pb push_back #define ff first #define ss second using namespace std; const int MX = 1e6 + 5; int n, q, l, r, cur; int p[MX], ans[MX], fix[MX], nxt[MX], tree[4 * MX]; pair<pair<int, int>, int> t[MX]; set<pair<pair<int, int>, int> > s; void update(int id, int l, int r, int x, int val) { if(l > x || r < x) return; tree[id] += val; if(l == r) return; int mid = (l + r) / 2; update(id * 2 + 1, l, mid, x, val); update(id * 2 + 2, mid + 1, r, x, val); } int sum(int id, int l, int r, int L, int R) { if(L > r || l > R) return 0; if(L <= l && r <= R) return tree[id]; int mid = (l + r) / 2; return sum(id * 2 + 1, l, mid, L, R) + sum(id * 2 + 2, mid + 1, r, L, R); } int find(int id, int l, int r, int x) { if(l == r) { if(tree[id] < x) return l; else return l - 1; } int mid = (l + r) / 2; if(tree[id * 2 + 1] < x) return find(id * 2 + 2, mid + 1, r, x - tree[id * 2 + 1]); else return find(id * 2 + 1, l, mid, x); } void pre() { while((*s.rbegin()).ff.ss + r <= n / 2) { for(int i = 0; i < (*s.rbegin()).ff.ss; i++) { fix[n - r - (*s.rbegin()).ff.ss + i] = p[(*s.rbegin()).ss + i]; } r += (*s.rbegin()).ff.ss; s.erase(*s.rbegin()); } } void go() { if(r == n / 2) return; pair<pair<int, int>, int> x = *s.rbegin(); s.erase(*s.rbegin()); s.insert({{x.ff.ff, x.ff.ss + r - n / 2}, x.ss}); update(0, 1, n, x.ff.ff, r - n / 2); int ind = x.ss + x.ff.ss + r - n / 2; while(ind < x.ss + x.ff.ss) { s.insert({{p[ind], min(nxt[ind], x.ss + x.ff.ss) - ind}, ind}); update(0, 1, n, p[ind], min(nxt[ind], x.ss + x.ff.ss) - ind); ind = nxt[ind]; } pre(); } int main() { ios::sync_with_stdio(0);cin.tie(0); memset(fix, -1, sizeof(fix)); cin >> n >> q; stack<pair<int, int > > st; for(int i = 0; i <= n; i++) { if (i != n) { cin >> p[i]; } else { p[i] = INT_MAX; } while(!st.empty() && st.top().ff < p[i]) { nxt[st.top().ss] = i; st.pop(); } st.push({p[i], i}); } while(l < n) { s.insert({{p[l], nxt[l] - l}, l}); update(0, 1, n, p[l], nxt[l] - l); l = nxt[l]; } pre(); for(int i = 0; i < q; i++) { cin >> t[i].ff.ff >> t[i].ff.ss; t[i].ss = i; if (t[i].ff.ff > n) t[i].ff.ff = n; } sort(t, t + q); for(int i = 0; i <= n; i++) { if(t[cur].ff.ff > i) { go(); continue; } while(cur < q && t[cur].ff.ff == i) { if(t[cur].ff.ss + r <= n) { int k = find(0, 1, n, t[cur].ff.ss) + 1; auto itr = s.lower_bound({{k, 0}, 0}); int cnt = sum(0, 1, n, 1, k - 1); ans[t[cur].ss] = p[(*itr).ss + t[cur].ff.ss - cnt - 1]; cur++; } else { ans[t[cur].ss] = fix[t[cur].ff.ss - 1]; cur++; } } go(); } for(int i = 0; i < q; i++) { cout << ans[i] << "\n"; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...