Submission #739729

#TimeUsernameProblemLanguageResultExecution timeMemory
739729danikoynovAbracadabra (CEOI22_abracadabra)C++14
100 / 100
1119 ms132232 KiB
/** ____ ____ ____ ____ ____ ____ ||l |||e |||i |||n |||a |||d || ||__|||__|||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|/__\|/__\| **/ #include<bits/stdc++.h> #define endl '\n' using namespace std; typedef long long ll; void speed() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); } const int maxn = 2e5 + 10, maxq = 1e6 + 10; int n, q, a[maxn], b[maxn], ans[maxq], nxt_pos[maxn], nxt_val[maxn]; vector < pair < int, int > > ask[maxn]; void shuffle_array() { deque < int > d1, d2; for (int i = 1; i <= n / 2; i ++) d1.push_back(a[i]); for (int i = n / 2 + 1; i <= n; i ++) d2.push_back(a[i]); deque < int > res; while(!d1.empty() && !d2.empty()) { if (d1.front() < d2.front()) { res.push_back(d1.front()); d1.pop_front(); } else { res.push_back(d2.front()); d2.pop_front(); } } while(!d1.empty()) { res.push_back(d1.front()); d1.pop_front(); } while(!d2.empty()) { res.push_back(d2.front()); d2.pop_front(); } for (int i = 1; i <= n; i ++) a[i] = res[i - 1]; } struct block { int val, left, right; block(int _val = 0, int _left = 0, int _right = 0) { val = _val; left = _left; right = _right; } bool operator < (const block &bk) const { if (val == bk.val) return right < bk.right; return val < bk.val; } }; set < block > act, blocks; int fin[maxn], to, sz; void shuffle_smart_init() { while(true) { block cur = *act.rbegin(); if (sz - (cur.right - cur.left + 1) + 1 > n / 2) { ///cout << "remove " << sz << " " << cur.left << " " << cur.right << endl; act.erase(cur); sz -= (cur.right - cur.left + 1); } else { break; } } if (sz == n / 2) return; /** for (block cur : act) { cout << "here " << cur.val << " " << cur.left << " " << cur.right << endl; }*/ block cur = *act.rbegin(); act.erase(cur); block fr = cur; fr.right = cur.right - (sz - n / 2); act.insert(fr); blocks.insert(fr); int idx = cur.right - (sz - n / 2) + 1, svd = idx; int sum_size = 0; //cout << idx << " : " << cur.right << endl; while(idx <= cur.right) { int gt = nxt_pos[idx]; gt = min(gt, cur.right + 1); sum_size += (gt - idx); act.insert(block(a[idx], idx, gt - 1)); blocks.insert(block(a[idx], idx, gt - 1)); idx = gt; } } unordered_map < int, int > rev[maxn]; block bl[maxn * 2]; int tree[8 * maxn]; int bl_cnt; void update(int root, int left, int right, int idx) { if (left == right) { if (tree[root] == 0) tree[root] = bl[left].right - bl[left].left + 1; else tree[root] = 0; return; } int mid = (left + right) / 2; if (idx <= mid) update(root * 2, left, mid, idx); else update(root * 2 + 1, mid + 1, right, idx); tree[root] = tree[root * 2] + tree[root * 2 + 1]; } int walk(int root, int left, int right, int k) { if (left == right) { return a[bl[left].left + k - 1]; } int mid = (left + right) / 2; if (tree[root * 2] >= k) return walk(root * 2, left, mid, k); else return walk(root * 2 + 1, mid + 1, right, k - tree[root * 2]); } void shuffle_smart() { while(true) { block cur = *act.rbegin(); if (sz - (cur.right - cur.left + 1) + 1 > n / 2) { ///cout << "remove " << sz << " " << cur.left << " " << cur.right << endl; act.erase(cur); sz -= (cur.right - cur.left + 1); } else { break; } } if (sz == n / 2) return; /** for (block cur : act) { cout << "here " << cur.val << " " << cur.left << " " << cur.right << endl; }*/ block cur = *act.rbegin(); act.erase(cur); update(1, 1, bl_cnt, rev[cur.left][cur.right]); block fr = cur; fr.right = cur.right - (sz - n / 2); act.insert(fr); update(1, 1, bl_cnt, rev[fr.left][fr.right]); int idx = cur.right - (sz - n / 2) + 1, svd = idx; int sum_size = 0; //cout << idx << " : " << cur.right << endl; while(idx <= cur.right) { int gt = nxt_pos[idx]; gt = min(gt, cur.right + 1); sum_size += (gt - idx); act.insert(block(a[idx], idx, gt - 1)); update(1, 1, bl_cnt, rev[idx][gt - 1]); idx = gt; } } void solve() { cin >> n >> q; for (int i = 1; i <= n; i ++) { cin >> a[i]; b[i] = a[i]; } int tp = 0; for (int i = 1; i <= q; i ++) { int t, v; cin >> t >> v; t = min(t, n); tp = t; if (t == 0) ans[i] = a[v]; else ask[t].push_back({v, i}); } shuffle_array(); /**for (int i = 1; i <= n; i ++) cout << a[i] << " "; cout << endl;*/ stack < int > st; for (int i = 1; i <= n; i ++) { while(!st.empty() && a[st.top()] < a[i]) { nxt_pos[st.top()] = i; st.pop(); } st.push(i); } while(!st.empty()) { nxt_pos[st.top()] = n + 1; st.pop(); } int i = 1; while(i <= n) { act.insert(block(a[i], i, nxt_pos[i] - 1)); blocks.insert(block(a[i], i, nxt_pos[i] - 1)); i = nxt_pos[i]; } to = n; sz = n; for (int f = 1; f <= n; f ++) { shuffle_smart_init(); } while(!act.empty()) { block cur = *act.rbegin(); ///cout << to << " " << sz << " " << (cur.right - cur.left + 1) << endl; act.erase(cur); sz -= (cur.right - cur.left + 1); } for (block cur : blocks) { rev[cur.left][cur.right] = ++ bl_cnt; bl[bl_cnt] = cur; ///cout << cur.val << " " << cur.left << " " << cur.right << endl; } for (int i = 1; i <= n; i ++) a[i] = b[i]; shuffle_array(); i = 1; while(i <= n) { act.insert(block(a[i], i, nxt_pos[i] - 1)); update(1, 1, bl_cnt, rev[i][nxt_pos[i] - 1]); ///blocks.insert(block(a[i], i, nxt_pos[i] - 1)); i = nxt_pos[i]; } to = n; sz = n; for (int f = 1; f <= n; f ++) { for (pair < int, int > cur : ask[f]) { ans[cur.second] = walk(1, 1, bl_cnt, cur.first); } shuffle_smart(); } for (int i = 1; i <= q; i ++) cout << ans[i] << endl; } int main() { speed(); solve(); return 0; } /** 10 0 3 8 2 4 9 5 10 1 6 7 */

Compilation message (stderr)

Main.cpp: In function 'void shuffle_smart_init()':
Main.cpp:117:45: warning: unused variable 'svd' [-Wunused-variable]
  117 |     int idx = cur.right - (sz - n / 2) + 1, svd = idx;
      |                                             ^~~
Main.cpp: In function 'void shuffle_smart()':
Main.cpp:202:45: warning: unused variable 'svd' [-Wunused-variable]
  202 |     int idx = cur.right - (sz - n / 2) + 1, svd = idx;
      |                                             ^~~
Main.cpp: In function 'void solve()':
Main.cpp:224:9: warning: variable 'tp' set but not used [-Wunused-but-set-variable]
  224 |     int tp = 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...