Treap

为了省事,我已不择手段

//
// Created by dhy on 18-12-2.
//
# include <cstdlib>
# include <cstdio>
int read(){
    int x = 0,f = 1;
    static char c = getchar();
    while(c<'0'||c>'9'){ if(c=='-')f = -1;c = getchar(); }
    while(c>='0'&&c<='9'){ x = (x<<1)+(x<<3)+c-'0';c = getchar(); }
    return x*f;
}
const int SIZE = 100010;
struct Treap{
    int l,r;
    int val,dat;//key code and weight
    int cnt,size;//
}tree[SIZE];
int tot,root,INF = 0x7fffffff;
int New(int val){
    tree[++tot].val = val;
    tree[tot].dat = rand();
    tree[tot].cnt = tree[tot].size = 1;
    return tot;
}
void update(int p){//左旋右旋以后,要更新一下
    tree[p].size = tree[tree[p].l].size+tree[tree[p].r].size+tree[p].cnt;
}
void build(){
    New(-INF),New(INF);
    root = 1;
    tree[1].r = 2;
    update(root);
}
int getRankByVal(int p,int val){
    if(p==0)return 0;//
    if(val==tree[p].val)return tree[tree[p].l].size+1;
    if(val<tree[p].val)return getRankByVal(tree[p].l,val);
    return getRankByVal(tree[p].r,val)+tree[tree[p].l].size+tree[p].cnt;
}
int getValByRank(int p,int rank){
    if(p==0)return INF;
    if(tree[tree[p].l].size>=rank)return getValByRank(tree[p].l,rank);
    if(tree[tree[p].l].size+tree[p].cnt>=rank)return tree[p].val;
    return getValByRank(tree[p].r,rank-tree[tree[p].l].size-tree[p].cnt);
}
void zig(int &p){//turn to right
    int q = tree[p].l;
    tree[p].l = tree[q].r,tree[q].r = p,p = q;
    update(tree[p].r);update(p);
}
void zag(int &p){//turn to left
    int q = tree[p].r;
    tree[p].r = tree[q].l;
    tree[q].l = p;
    p = q;
    update(tree[p].l);
    update(p);
}
void insert(int &p,int val){
    if(p==0){
        p = New(val);
        return;
    }
    if(val == tree[p].val){
        tree[p].cnt++;
        update(p);
        return;
    }
    if(val<tree[p].val){
        insert(tree[p].l,val);
        if(tree[p].dat<tree[tree[p].l].dat)zig(p);//就是插入节点以后,右旋上来
    }else{
        insert(tree[p].r,val);
        if(tree[p].dat<tree[tree[p].r].dat)zag(p);//插入到右子树,左旋上来
    }
    update(p);
}
int getPre(int val){
    int ans = 1;
    int p = root;
    while(p){
        if(val==tree[p].val){
            if(tree[p].l>0){
                p = tree[p].l;
                while(tree[p].r>0)p = tree[p].r;//找到val,然后从val的左节点开始,一路向右走
                ans = p;
            }
            break;
        }
        if(tree[p].val<val&&tree[p].val>tree[ans].val)ans = p;//找前驱,不断更新ans
        p = val<tree[p].val?tree[p].l:tree[p].r;//左走右走
    }
    return tree[ans].val;
}
int getNext(int val){
    int ans = 2;
    int p = root;
    while(p){
        if(val==tree[p].val){
            if(tree[p].r>0){
                p = tree[p].r;
                while(tree[p].l>0)p = tree[p].l;//后继,和上面一样的
                ans = p;
            }
            break;
        }
        if(tree[p].val>val&&tree[p].val<tree[ans].val)ans = p;
        p = val<tree[p].val?tree[p].l:tree[p].r;
    }
    return tree[ans].val;
}
void remove(int &p,int val){
    if(p==0)return;
    if(tree[p].val==val){
        if(tree[p].cnt>1){
            tree[p].cnt--;
            update(p);
            return;
        }
        if(tree[p].l||tree[p].r){//左右子树有一个不为0
            if(tree[p].r==0||tree[tree[p].l].dat>tree[tree[p].r].dat)
                zig(p),remove(tree[p].r,val);
            else
                zag(p),remove(tree[p].l,val);
            update(p);
        }
        else
            p = 0;
        return;
    }
    val<tree[p].val?remove(tree[p].l,val):remove(tree[p].r,val);
    update(p);
}
int main(){
    build();
    int n = read();
    while(n--){
        int opt,x;
        opt = read(),x = read();
        switch (opt){
            case 1:
                insert(root,x);
                break;
            case 2:
                remove(root,x);
                break;
            case 3:
                printf("%d\n",getRankByVal(root,x)-1);
                break;
            case 4:
                printf("%d\n",getValByRank(root,x+1));
                break;
            case 5:
                printf("%d\n",getPre(x));
                break;
            case 6:
                printf("%d\n",getNext(x));
                break;
        }
    }
    return 0;
}