Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // randomized cartesian tree
- #include <bits/stdc++.h>
- using namespace std;
- mt19937 rng (12345);
- struct Node;
- typedef Node * PNode;
- struct Node
- {
- int x;
- int size;
- PNode left;
- PNode right;
- Node (int x_)
- {
- x = x_;
- size = 1;
- left = right = nullptr;
- }
- };
- void recalc (PNode t)
- {
- if (t == nullptr) return;
- t -> size = 1;
- if (t -> left != nullptr)
- t -> size += t -> left -> size;
- if (t -> right != nullptr)
- t -> size += t -> right -> size;
- }
- pair <PNode, PNode> tsplit (PNode t, int xs)
- {
- if (t == nullptr) return {nullptr, nullptr};
- if (t -> x < xs)
- { // t->left t->x | t->right, xs
- // t->left | t->x | temp.first | temp.second
- auto temp = tsplit (t -> right, xs);
- t -> right = temp.first;
- recalc (t);
- return {t, temp.second};
- }
- else
- { // t->left, xs | t->x | t->right
- // temp.first | temp.second / t->x \ t->right
- auto temp = tsplit (t -> left, xs);
- t -> left = temp.second;
- recalc (t);
- return {temp.first, t};
- }
- }
- PNode tmerge (PNode l, PNode r)
- {
- if (l == nullptr) return r;
- if (r == nullptr) return l;
- // (100) 100/110 (10) 10/110
- if (rng () % (l -> size + r -> size) < (unsigned) l -> size)
- { // l
- // / \ .
- // l->left l->right r
- l -> right = tmerge (l -> right, r);
- recalc (l);
- return l;
- }
- else
- { // r
- // / \ .
- // l r->left r->right
- r -> left = tmerge (l, r -> left);
- recalc (r);
- return r;
- }
- }
- PNode tadd (PNode t, int x)
- {
- auto temp = tsplit (t, x);
- auto cur = new Node (x);
- // temp.first | cur | temp.second
- auto m = tmerge (temp.first, cur);
- return tmerge (m, temp.second);
- }
- PNode trem (PNode t, int x)
- {
- auto temp = tsplit (t, x);
- auto temp2 = tsplit (temp.second, x + 1);
- // temp.first (< x) | temp2.first (== x) | temp2.second (> x)
- return tmerge (temp.first, temp2.second);
- }
- void toutput (PNode t, string history = "")
- {
- if (t == nullptr) return;
- toutput (t -> left, history + " ");
- cout << history << "" << t -> x << endl;
- toutput (t -> right, history + " ");
- }
- int tfind(PNode t, int k, int cu){
- int tmpll = 0, tmprr = 0, tmplr = 0, tmprl = 0;
- if(t -> left != nullptr){
- if(t -> left -> left != nullptr) tmpll = t -> left -> left -> size;
- if(t -> left -> right != nullptr) tmplr = t -> left -> right -> size;
- }
- if(t -> right != nullptr){
- if(t -> right -> left != nullptr) tmprl = t -> right -> left -> size;
- if(t -> right -> right != nullptr) tmprr = t -> right -> right -> size;
- }
- //cout << t -> x << " size " << t->size << " cur " << cu << " tmprl " << tmprl << " tmprr" << tmprr << endl;
- if(k - 1 == cu){
- return t -> x;
- }
- if(t -> right != nullptr){
- if(cu < k - 1){
- tfind(t -> left, k, cu + tmplr + 1);
- }
- else tfind(t -> right, k, cu - tmprl - 1);
- }
- else{
- tfind(t -> left, k, cu + tmplr + 1);
- }
- }
- PNode root;
- int main ()
- {
- ios_base::sync_with_stdio (false);
- cin.tie (0);
- cout.tie (0);
- root = nullptr;
- int n;
- cin >> n;
- for(int i = 0; i < n; ++i){
- int a, b;
- cin >> a >> b;
- if(a == +1){
- root = tadd(root, b);
- //toutput(root);
- }
- if(a == -1){
- root = trem(root, b);
- }
- if(a == 0){
- int tmp = 0;
- if(root -> right != nullptr){
- tmp = root -> right -> size;
- }
- cout << tfind(root, b, tmp) << endl;
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement