#include #include using namespace std; mt19937 MyLittleRandom(100500); struct Node { int x; int y; int sz; int sum; Node* left; Node* right; Node(int cx) { x = cx; y = MyLittleRandom(); sz = 1; sum = x; left = nullptr; right = nullptr; } void update() { sz = 1; if (left != nullptr) sz += left->sz; if (right != nullptr) sz += right->sz; sum = x; if (left != nullptr) sum += left->sum; if (right != nullptr) sum += right->sum; } }; // ===== pair split(Node* root, int x, bool equal_value_to_right = true) { // < and >= if (root == nullptr) { return make_pair(nullptr, nullptr); } if (root->x < x || (root->x == x && !equal_value_to_right)) { auto res = split(root->right, x, equal_value_to_right); root->right = res.first; root->update(); return make_pair(root, res.second); } else { auto res = split(root->left, x, equal_value_to_right); root->left = res.second; root->update(); return make_pair(res.first, root); } } pair split_k(Node* root, int k) { if (root == nullptr) { return make_pair(nullptr, nullptr); } if (root->left != nullptr) { if (root->left->sz >= k) { auto res = split_k(root->left, k); root->left = res.second; root->update(); return make_pair(res.first, root); } else k -= root->left->sz; } if (k == 0) { return make_pair(nullptr, root); } auto res = split_k(root->right, k - 1); root->right = res.first; root->update(); return make_pair(root, res.second); } Node* merge(Node* l, Node* r) { if (l == nullptr) return r; if (r == nullptr) return l; if (l->y < r->y) { r->left = merge(l, r->left); r->update(); return r; } else { l->right = merge(l->right, r); l->update(); return l; } } // ===== Node* insert(Node* root, int x) { auto res = split(root, x); Node* x_tree = new Node(x); root = merge(x_tree, res.second); return merge(res.first, root); } Node* remove(Node* root, int x) { auto res = split(root, x); root = res.first; res = split(res.second, x, false); return merge(root, res.second); } Node* insert_k(Node* root, int x, int k) { auto res = split_k(root, k); Node* x_tree = new Node(x); root = merge(x_tree, res.second); return merge(res.first, root); } Node* remove_k(Node* root, int k) { auto res = split_k(root, k); root = res.first; res = split_k(res.second, 1); return merge(root, res.second); } Node* find(Node* root, int x) { if (root == nullptr) return nullptr; if (root->x == x) return root; if (root->x < x) { return find(root->right, x); } else { return find(root->left, x); } } Node* kth_element(Node* root, int k) { // 1-based if (root == nullptr) return nullptr; if (root->left != nullptr) { if (root->left->sz >= k) { return kth_element(root->left, k); } else k -= root->left->sz; } if (k == 1) { return root; } return kth_element(root->right, k - 1); } pair segment_sum(Node* root, int l, int r) { // [l, r] auto res_1 = split_k(root, r); auto res_2 = split_k(res_1.first, l - 1); int ans = 0; if (res_2.second != nullptr) ans = res_2.second->sum; root = merge(res_2.first, res_2.second); root = merge(root, res_1.second); return make_pair(root, ans); } // ===== int main() { Node* root = nullptr; while (true) { char ch; cin >> ch; if (ch == '+') { int x, k; cin >> x >> k; root = insert_k(root, x, k); } if (ch == '-') { int k; cin >> k; root = remove_k(root, k); } /* if (ch == '?') { int x; cin >> x; auto res = find(root, x); if (res == nullptr) cout << "NO" << endl; else cout << "YES" << endl; } */ if (ch == 'k') { int k; cin >> k; auto res = kth_element(root, k); if (res == nullptr) cout << "NO" << endl; else cout << res->x << endl; } } return 0; }