#include #include using namespace std; mt19937 rng(100500); struct Node { int x; //int y; int sz; int mx; int sum; bool make_null; bool reverse; Node* left; Node* right; Node(int cx = 0) { x = cx; //y = rng(); sz = 1; mx = x; sum = x; make_null = false; reverse = false; left = nullptr; right = nullptr; } Node(Node* v) { x = v->x; sz = v->sz; mx = v->mx; sum = v->sum; make_null = v->make_null; reverse = v->reverse; left = v->left; right = v->right; } void push() { if (make_null) { make_null = false; x = 0; if (left != nullptr) { left->make_null = true; left->upd(); } if (right != nullptr) { right->make_null = true; right->upd(); } } if (reverse) { reverse = false; swap(left, right); if (left != nullptr) { left->reverse = true; left->upd(); } if (right != nullptr) { right->reverse = true; right->upd(); } } } void upd() { sz = 1; if (left != nullptr) sz += left->sz; if (right != nullptr) sz += right->sz; mx = x; if (left != nullptr) mx = max(mx, left->mx); if (right != nullptr) mx = max(mx, right->mx); if (make_null) mx = 0; sum = x; if (left != nullptr) sum = sum + left->sum; if (right != nullptr) sum = sum + right->sum; if (make_null) sum = 0; } }; pair split(Node* root, int x) { // < & >= if (!root) { return make_pair(nullptr, nullptr); } if (root->x < x) { root->push(); auto res = split(root->right, x); root = new Node(root); root->right = res.first; root->upd(); res.first = root; return res; } else { root->push(); auto res = split(root->left, x); root = new Node(root); root->left = res.second; root->upd(); res.second = root; return res; } } pair split_sz(Node* root, int k) { // k = left->sz if (!root) { return make_pair(nullptr, nullptr); } if (root->left != nullptr) { if (k <= root->left->sz) { root->push(); auto res = split_sz(root->left, k); root = new Node(root); root->left = res.second; root->upd(); res.second = root; return res; } else k -= root->left->sz; } if (k == 0) { root->push(); auto res = root->left; root = new Node(root); root->left = nullptr; root->upd(); return make_pair(res, root); } root->push(); auto res = split_sz(root->right, k - 1); root = new Node(root); root->right = res.first; root->upd(); res.first = root; return res; } Node* merge(Node* l, Node* r) { if (!l) { return r; } if (!r) { return l; } if (rng() * 1.0 / rng.max() < l->sz * 1.0 / (l->sz + r->sz)) { l->push(); l = new Node(l); l->right = merge(l->right, r); l->upd(); return l; } else { r->push(); r = new Node(r); r->left = merge(l, r->left); r->upd(); return r; } } // ===== Node* insert(Node* root, int x) { auto res = split(root, x); Node* node_x = new Node(x); root = merge(res.first, node_x); root = merge(root, res.second); return root; } Node* remove(Node* root, int x) { auto res = split(root, x); auto res_2 = split(res.second, x + 1); return merge(res.first, res_2.second); } bool find(Node* root, int x) { if (root == nullptr) return false; if (root->x == x) return true; if (root->x < x) return find(root->right, x); else return find(root->left, x); } int kth_element(Node* root, int k) { if (root == nullptr) return -1; root->push(); if (root->left != nullptr) { if (k < root->left->sz) return kth_element(root->left, k); else k -= root->left->sz; } if (k == 0) return root->x; else return kth_element(root->right, k - 1); } Node* insert_sz(Node* root, int k, int x) { auto res = split_sz(root, k); Node* node_x = new Node(x); root = merge(res.first, node_x); root = merge(root, res.second); return root; } Node* remove_sz(Node* root, int k) { auto res = split_sz(root, k); auto res_2 = split_sz(res.second, 1); return merge(res.first, res_2.second); } Node* switch_segments(Node* root, int lo, int me, int hi) { auto res = split_sz(root, me); auto res_l = split_sz(res.first, lo); auto res_r = split_sz(res.second, hi - me); root = merge(res_l.first, res_r.first); root = merge(root, res_l.second); root = merge(root, res_r.second); return root; } pair max_segment(Node* root, int l, int r) { auto res = split_sz(root, r); auto res_1 = split_sz(res.first, l); int mx = res_1.second->mx; root = merge(res_1.first, res_1.second); root = merge(root, res.second); return make_pair(mx, root); } Node* null_segment(Node* root, int l, int r) { auto res = split_sz(root, r); auto res_1 = split_sz(res.first, l); res_1.second->make_null = true; root = merge(res_1.first, res_1.second); root = merge(root, res.second); return root; } Node* reverse_segment(Node* root, int l, int r) { auto res = split_sz(root, r); auto res_1 = split_sz(res.first, l); res_1.second->reverse = true; root = merge(res_1.first, res_1.second); root = merge(root, res.second); return root; } Node* append_segment(Node* root, int l, int r) { auto res = split_sz(root, r); auto res_1 = split_sz(res.first, l); return merge(root, res_1.second); } pair sum_segment(Node* root, int l, int r) { auto res = split_sz(root, r); auto res_1 = split_sz(res.first, l); int sum = res_1.second->sum; root = merge(res_1.first, res_1.second); root = merge(root, res.second); return make_pair(sum, root); } // ===== int main() { Node* root = nullptr; vector root_history = { nullptr }; while (true) { char ch; cin >> ch; if (ch == '+') { int k; int x; cin >> k >> x; root = insert_sz(root, k, x); } if (ch == '-') { int k; cin >> k; root = remove_sz(root, k); } if (ch == '?') { int k, t; cin >> k >> t; cout << kth_element(root_history[t], k) << endl; } if (ch == 'S') { int lo, me, hi; cin >> lo >> me >> hi; root = switch_segments(root, lo, me, hi); } if (ch == 'M') { int l, r, t; cin >> l >> r >> t; auto res = max_segment(root_history[t], l, r); //root = res.second; cout << res.first << endl; } if (ch == 's') { int l, r, t; cin >> l >> r >> t; auto res = sum_segment(root_history[t], l, r); //root = res.second; cout << res.first << endl; } if (ch == '0') { int l, r; cin >> l >> r; root = null_segment(root, l, r); } if (ch == 'R') { int l, r; cin >> l >> r; root = reverse_segment(root, l, r); } if (ch == 'A') { int l, r; cin >> l >> r; root = append_segment(root, l, r); } root_history.push_back(root); cout << "# " << root_history.size() - 1 << endl; } return 0; }