[bzoj3196][tyvj1728]普通平衡树

真是太差了,到现在才打出一个平衡树的板子。。

感谢blackjack大佬提供的数组版treap板子!!基本完全照搬,blackjack太神啦!

但目前我只会这几个最基本的操作(说白了STL的(multi)set)也能干。。。

还差的好远-_-

#include<bits/stdc++.h>
#define L T[x].ls
#define R T[x].rs
using namespace std;
const int N=100010;
int root,sz,ans;
struct Node{
    int val,sz,cnt,ls,rs,key;
}T[N];
void ref(int x){
    T[x].sz=T[L].sz+T[R].sz+T[x].cnt;
}
void zig(int &x){
    int y=R;
    T[x].rs=T[y].ls;T[y].ls=x;
    T[y].sz=T[x].sz;ref(x);ref(y);x=y;
}
void zag(int &x){
    int y=L;
    T[x].ls=T[y].rs;T[y].rs=x;
    T[y].sz=T[x].sz;ref(x);ref(y);x=y;
}
void ins(int &x,int v){
    if(!x){
        x=++sz;
        T[x]=(Node){v,1,1,0,0,rand()};
        return;
    }
    if(T[x].val==v){
        T[x].cnt++;T[x].sz++;
        return;
    }
    T[x].sz++;
    if(T[x].val<v){
        ins(R,v);
        if(T[R].key<T[x].key)
        zig(x);
    }
    else{
        ins(L,v);
        if(T[L].key<T[x].key)
        zag(x);
    }
}
void del(int &x,int v){
    if(!x)return;
    if(T[x].val==v){
        if(T[x].cnt>1){
            T[x].cnt--;T[x].sz--;
            return;
        }
        if(!(L*R)){
            x=L+R;return;
        }
        if(T[L].key<T[R].key)
            zag(x),del(x,v);
        else
            zig(x),del(x,v);
    }
    else{
        T[x].sz--;
        if(T[x].val<v)del(R,v);
        else del(L,v);
    }
}
void pre(int x,int v){
    if(!x)return;
    if(T[x].val<v)
    ans=x,pre(R,v);
    else pre(L,v);
}
void nxt(int x,int v){
    if(!x)return;
    if(T[x].val>v)
    ans=x,nxt(L,v);
    else nxt(R,v);
}
int qnum(int x,int rk){
    if(!x)return 0;
    if(rk<=T[L].sz)
    return qnum(L,rk);
    if(rk>T[L].sz+T[x].cnt)
    return qnum(R,rk-T[L].sz-T[x].cnt);
    return T[x].val;
}
int qrank(int x,int v){
    if(!x)return 0;
    if(T[x].val==v)
    return T[L].sz+1;
    if(T[x].val<v)
    return qrank(R,v)+T[L].sz+T[x].cnt;
    return qrank(L,v);
}
int main(){
    int n;scanf("%d",&n);
    while(n--){
        int opt,t;scanf("%d%d",&opt,&t);
        ans=0;
        switch(opt){
            case 1:ins(root,t);break;
            case 2:del(root,t);break;
            case 3:ans=qrank(root,t);printf("%d\n",ans);break;
            case 4:ans=qnum(root,t);printf("%d\n",ans);break;
            case 5:pre(root,t);printf("%d\n",T[ans].val);break;
            case 6:nxt(root,t);printf("%d\n",T[ans].val);break;
        }
    }
}

 

posted @ 2017-09-11 11:03  orzzz  阅读(188)  评论(0编辑  收藏  举报