[BZOJ3224]Tyvj 1728 普通平衡树

原题地址

BZOJ不能用time(0)!!!

BZOJ不能用time(0)!!!

BZOJ不能用time(0)!!!

用了就RE!!!要直接用rand()!!!

妈呀调了大半个晚上简直呵呵呵…
这题可以当我的FHQ_Theap模板了…

#include <cstdio>
#include <cstdlib>
const int N=100010;
int n,tot;

struct nod{
    int val,size,fix;
    nod *lc,*rc;
}pool[N],*NIL;

struct Treap{
    nod *root;

    Treap(){
        root=NIL=&pool[tot++];
    }

    void update(nod *p){
        p->size=p->lc->size+p->rc->size+1;
    }
    nod* merge(nod *p1,nod *p2){
        if(p1==NIL) return p2;
        if(p2==NIL) return p1;
        if(p1->fix<p2->fix){
            p2->lc=merge(p1,p2->lc);
            update(p2);
            return p2;
        }
        p1->rc=merge(p1->rc,p2);
        update(p1);
        return p1;
    }
    void split(nod *p,nod *&p1,nod *&p2,int k){
        if(p==NIL){
            p1=p2=NIL;
            return ;
        }
        if(p->lc->size+1>k){
            split(p->lc,p1,p2,k);
            p->lc=NIL;
            update(p);
            p2=merge(p2,p);
        }
        else{
            split(p->rc,p1,p2,k-p->lc->size-1);
            p->rc=NIL;
            update(p);
            p1=merge(p,p1);
        }
    }
    int getrank(nod *p,int x){
        if(p==NIL) return 1;
        return p->val>=x?getrank(p->lc,x):getrank(p->rc,x)+p->lc->size+1;
    }
    nod* newnod(int x){
        nod *p=&pool[tot++];
        p->val=x;p->size=1;p->fix=rand()*rand()%N;p->lc=p->rc=NIL;
        return p;
    }
    void insert(int x){
        nod *p1,*p2;
        split(root,p1,p2,getrank(root,x)-1);
        root=merge(merge(p1,newnod(x)),p2);
    }
    void erase(int x){
        nod *p1,*p2,*p3,*p4;
        split(root,p1,p2,getrank(root,x)-1);
        split(p2,p3,p4,1);
        root=merge(p1,p4);
    }
    void getkth(int x){
        nod *p1,*p2,*p3,*p4;
        split(root,p1,p2,x-1);
        split(p2,p3,p4,1);
        printf("%d\n",p3->val);
        root=merge(merge(p1,p3),p4);
    }
    nod* getpre(nod *p,int x){
        if(p==NIL) return p;
        if(p->val>=x) return getpre(p->lc,x);
        nod *q=getpre(p->rc,x);
        return q!=NIL?q:p;
    }
    nod* getsuc(nod *p,int x){
        if(p==NIL) return p;
        if(p->val<=x) return getsuc(p->rc,x);
        nod *q=getsuc(p->lc,x);
        return q!=NIL?q:p;
    }
}T;

int main(){
    scanf("%d",&n);
    while(n--){
        int opt,x;
        scanf("%d%d",&opt,&x);
        if(opt==1) T.insert(x);
        else if(opt==2) T.erase(x);
        else if(opt==3) printf("%d\n",T.getrank(T.root,x));
        else if(opt==4) T.getkth(x);
        else if(opt==5) printf("%d\n",T.getpre(T.root,x)->val);
        else printf("%d\n",T.getsuc(T.root,x)->val);
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值