【Treap】[CQBZOJ2803]普通平衡树

粘模板

#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 500000
int n,pre,bk;
struct node{
    int val,pri,cnt,lsize,rsize;
    node *ls,*rs;
}treap_tree[MAXN+10],*tcnt=treap_tree,*root;
void Read(int &x){
    char c;
    bool f=0;
    while(c=getchar(),c!=EOF){
        if(c=='-')
            f=1;
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            if(f)
                x=-x;
            return;
        }
    }
}
void Rotate_left(node *&a){
    node *b=a->rs;
    a->rs=b->ls;
    b->ls=a;
    a->rsize=b->lsize;
    b->lsize=a->lsize+a->rsize+a->cnt;
    a=b;
}
void Rotate_right(node *&a){
    node *b=a->ls;
    a->ls=b->rs;
    b->rs=a;
    a->lsize=b->rsize;
    b->rsize=a->lsize+a->rsize+a->cnt;
    a=b;
}
void del(node *&p,int val){
    if(p->val==val){
        if(p->cnt>1){
            p->cnt--;
            return;
        }
        if(!p->ls||!p->rs){
            if(p->ls)
                p=p->ls;
            else
                p=p->rs;
            return;
        }
        if(p->ls->pri<p->rs->pri){
            Rotate_right(p);
            p->rsize--;
            del(p->rs,val);
        }
        else{
            Rotate_left(p);
            p->lsize--;
            del(p->ls,val);
        }
    }
    else if(val<p->val){
        p->lsize--;
        del(p->ls,val);
    }
    else{
        p->rsize--;
        del(p->rs,val);
    }
}
void Treap_insert(node *&p,int val){
    if(!p){
        p=++tcnt;
        p->cnt=1;
        p->val=val;
        p->ls=p->rs=NULL;
        p->pri=rand();
        return;
    }
    if(val>p->val){
        p->rsize++;
        Treap_insert(p->rs,val);
        if(p->rs->pri<p->pri)
            Rotate_left(p);
    }
    else if(val<p->val){
        p->lsize++;
        Treap_insert(p->ls,val);
        if(p->ls->pri<p->pri)
            Rotate_right(p);
    }
    else
        p->cnt++;
}
int find_pos(node *&p,int val){
    if(!p)
        return 0;
    if(p->val>val)
        return find_pos(p->ls,val);
    if(p->val<val)
        return p->lsize+p->cnt+find_pos(p->rs,val);
    return p->lsize;
}
void find_pre(node *&p,int val){
    if(!p)
        return;
    if(p->val<val){
        pre=p->val;
        find_pre(p->rs,val);
    }
    else
        find_pre(p->ls,val);
}
void find_bk(node *&p,int val){
    if(!p)
        return;
    if(p->val>val)
    {
        bk=p->val;
        find_bk(p->ls,val);
    }
    else
        find_bk(p->rs,val);
}
void pos_find(node *&p,int pos){
    if(pos<p->lsize)
        pos_find(p->ls,pos);
    else if(pos>=p->lsize+p->cnt)
        pos_find(p->rs,pos-p->lsize-p->cnt);
    else
        printf("%d\n",p->val);
}
int main()
{
    int i,a,b;
    srand(2015111820);
    Read(n);
    for(i=1;i<=n;i++){
        Read(a),Read(b);
        if(a==1)
            Treap_insert(root,b);
        else if(a==2)
            del(root,b);
        else if(a==3)
            printf("%d\n",find_pos(root,b)+1);
        else if(a==4)
            pos_find(root,b-1);
        else if(a==5){
            find_pre(root,b);
            printf("%d\n",pre);
        }
        else{
            find_bk(root,b);
            printf("%d\n",bk);
        }
    }
}
posted @ 2015-11-18 22:21  outer_form  阅读(164)  评论(0编辑  收藏  举报