제출 #1288171

#제출 시각아이디문제언어결과실행 시간메모리
1288171stefanneaguAbracadabra (CEOI22_abracadabra)C++20
100 / 100
712 ms63432 KiB
#include <bits/stdc++.h> // #define int long long using namespace std; const int nmax = 2e6 + 1; int v[nmax]; int ng[nmax]; int n; struct aib { int aib[nmax]; void upd(int a, int val) { while (a < nmax) { aib[a] += val; a += (a & (-a)); } } int qry(int a) { if (a == 0) return 0; int ans = 0; while (a > 0) { ans += aib[a]; a -= (a & (-a)); } return ans; } } aib1, aib2; void next_gr() { stack<int> st; for (int i = 1; i <= n; i++) { while (!st.empty() && v[st.top()] < v[i]) { ng[st.top()] = i; st.pop(); } st.push(i); } while (!st.empty()) { ng[st.top()] = n + 1; st.pop(); } } void build(int l, int r, vector<pair<int, int>> &vv) { while (l <= r) { if (ng[l] - 1 < r) { vv.push_back({l, ng[l] - 1}); l = ng[l]; } else { vv.push_back({l, r}); return; } } } void build2(int l, int r, vector<array<int, 3>> &vv) { while (l <= r) { if (ng[l] - 1 < r) { vv.push_back({v[l], l, ng[l] - 1}); l = ng[l]; } else { vv.push_back({v[l], l, r}); return; } } } struct qry { int t, loc; } qq[nmax]; vector<pair<int, int>> qrs[nmax]; int ans[nmax]; set<int> in1, in2; pair<int, int> solve1(int loc) { int st = 1, dr = n, ans = -1, plm = -1; while (st <= dr) { int mid = (st + dr) / 2; int cur = aib1.qry(mid); if (cur >= loc) { plm = cur; ans = mid; dr = mid - 1; } else { st = mid + 1; } } return {ans, (aib1.qry(ans) - aib1.qry(ans - 1)) - (plm - loc) - 1}; } pair<int, int> solve2(int loc) { int st = 1, dr = n, ans = -1, plm = -1; while (st <= dr) { int mid = (st + dr) / 2; int cur = aib2.qry(mid); if (cur >= loc) { plm = cur; ans = mid; dr = mid - 1; } else { st = mid + 1; } } return {ans, (aib2.qry(ans) - aib2.qry(ans - 1)) - (plm - loc) - 1}; } int back[nmax]; int32_t main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int q; cin >> n >> q; for (int i = 1; i <= n; i++) { cin >> v[i]; back[v[i]] = i; } for (int i = 1; i <= q; i++) { cin >> qq[i].t >> qq[i].loc; if (qq[i].t == 0) { ans[i] = v[qq[i].loc]; } else { if (qq[i].t < nmax) { qrs[qq[i].t].push_back({qq[i].loc, i}); } } } next_gr(); vector<pair<int, int>> v1, v2; build(1, n / 2, v1); build(n / 2 + 1, n, v2); set<array<int, 3>> s1, s2; int iv1 = 0, iv2 = 0, sz1 = 0; while (iv1 < v1.size() || iv2 < v2.size()) { if (iv2 == v2.size() || (iv1 < v1.size() && v[v1[iv1].first] < v[v2[iv2].first])) { if (sz1 < n / 2) { sz1 += v1[iv1].second - v1[iv1].first + 1; s1.insert({v[v1[iv1].first], v1[iv1].first, v1[iv1].second}); in1.insert(v[v1[iv1].first]); aib1.upd(v[v1[iv1].first], v1[iv1].second - v1[iv1].first + 1); } else { s2.insert({v[v1[iv1].first], v1[iv1].first, v1[iv1].second}); in2.insert(v[v1[iv1].first]); aib2.upd(v[v1[iv1].first], v1[iv1].second - v1[iv1].first + 1); } iv1++; } else { if (sz1 < n / 2) { sz1 += v2[iv2].second - v2[iv2].first + 1; aib1.upd(v[v2[iv2].first], v2[iv2].second - v2[iv2].first + 1); in1.insert(v[v2[iv2].first]); s1.insert({v[v2[iv2].first], v2[iv2].first, v2[iv2].second}); } else { aib2.upd(v[v2[iv2].first], v2[iv2].second - v2[iv2].first + 1); in2.insert(v[v2[iv2].first]); s2.insert({v[v2[iv2].first], v2[iv2].first, v2[iv2].second}); } iv2++; } } for (auto [it, ind] : qrs[1]) { if (it <= sz1) { auto [haha, ramas] = solve1(it); ans[ind] = v[back[haha] + ramas]; } else { auto [haha, ramas] = solve2(it - sz1); ans[ind] = v[back[haha] + ramas]; } } for (int _ = 2; _ < nmax; _++) { vector<pair<int, int>> extra; if (sz1 == n / 2) break; while (sz1 > n / 2) { auto [val, l, r] = *s1.rbegin(); s1.erase({val, l, r}); in1.erase(val); aib1.upd(v[l], -(r - l + 1)); if (sz1 - (r - l + 1) >= n / 2) { extra.push_back({l, r}); sz1 -= r - l + 1; } else { int cat_mai_trebe = sz1 - n / 2; int rnou = r - cat_mai_trebe; s1.insert({val, l, rnou}); in1.insert(val); aib1.upd(v[l], rnou - l + 1); extra.push_back({rnou + 1, r}); break; } } vector<array<int, 3>> cur; for (auto it : extra) { build2(it.first, it.second, cur); } vector<array<int, 3>> pe1, pe2; int s1rbegin = (*s1.rbegin())[0]; for (auto [val, l, r] : cur) { if (s1rbegin > val) { pe1.push_back({val, l, r}); } else { pe2.push_back({val, l, r}); } } for (auto it : pe1) { s1.insert(it); in1.insert(it[0]); aib1.upd(v[it[1]], it[2] - it[1] + 1); } for (auto it : pe2) { s2.insert(it); in2.insert(it[0]); aib2.upd(v[it[1]], it[2] - it[1] + 1); } for (auto [it, ind] : qrs[_]) { if (it <= sz1) { auto [haha, ramas] = solve1(it); ans[ind] = v[back[haha] + ramas]; } else { auto [haha, ramas] = solve2(it - sz1); ans[ind] = v[back[haha] + ramas]; } } } for (int i = 1; i <= q; i++) { if (!ans[i]) { auto [it, ind] = pair<int, int>{qq[i].loc, i}; if (it <= sz1) { auto [haha, ramas] = solve1(it); ans[ind] = v[back[haha] + ramas]; } else { auto [haha, ramas] = solve2(it - sz1); ans[ind] = v[back[haha] + ramas]; } } 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...