#include #include using namespace std; mt19937 rng(100500); struct Node { int x; int y; int sz; int mx; Node* left; Node* right; Node(int cx = 0) { x = cx; y = rng(); sz = 1; mx = x; left = nullptr; right = nullptr; } 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); } }; pair split(Node* root, int x) { // < & >= if (!root) { return make_pair(nullptr, nullptr); } if (root->x < x) { auto res = split(root->right, x); root->right = res.first; root->upd(); res.first = root; return res; } else { auto res = split(root->left, x); 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) { auto res = split_sz(root->left, k); root->left = res.second; root->upd(); res.second = root; return res; } else k -= root->left->sz; } if (k == 0) { auto res = root->left; root->left = nullptr; root->upd(); return make_pair(res, root); } auto res = split_sz(root->right, k - 1); 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 (l->y > r->y) { l->right = merge(l->right, r); l->upd(); return l; } else { 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; 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); } // ===== int main() { Node* root = 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; cin >> k; cout << kth_element(root, 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; cin >> l >> r; auto res = max_segment(root, l, r); root = res.second; cout << res.first << endl; } } return 0; }