1. 程式人生 > >【Treap】[BZOJ 3224]Tyvj 1728 普通平衡樹 & 非旋轉實現

【Treap】[BZOJ 3224]Tyvj 1728 普通平衡樹 & 非旋轉實現

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 2000005

struct Treap{
    Treap *l,*r;
    int fix,key,size;
    Treap(int key_){
        fix = rand();
        l = r = NULL;
        size = 1;
        key = key_;
    }

    inline void updata(){
        size=1
+(l?l->size:0)+(r?r->size:0); } }*root; struct Droot{ Treap *first, *second; Droot(){first = second = NULL;} }; Droot D_NULL; inline int Size(Treap *x){return x?x->size:0;} Treap *Merge(Treap *A,Treap *B){ if(!A)return B; if(!B)return A; if(A->fix<B->fix){ A->r=Merge(A->r,B); A->updata(); return
A; }else{ B->l=Merge(A,B->l); B->updata(); return B; } } Droot Split(Treap *x,int k){ if(!x)return D_NULL; Droot y; if(Size(x->l)>=k){ y=Split(x->l,k); x->l=y.second; x->updata(); y.second=x; }else
{ y=Split(x->r,k-Size(x->l)-1); x->r=y.first; x->updata(); y.first=x; } return y; } int Findkth(int k){ Droot x=Split(root,k-1); Droot y=Split(x.second,1); Treap *ans=y.first; root=Merge(Merge(x.first,ans),y.second); return ans->key; } int Getkth(Treap *x,int v){ if(!x)return 0; return v<=x->key?Getkth(x->l,v):Getkth(x->r,v)+Size(x->l)+1; } void Insert(int v){ int k=Getkth(root,v); Droot x=Split(root,k); Treap *n=new Treap(v); root=Merge(Merge(x.first,n),x.second); } void Delete(int k){ int pos = Getkth(root, k); Droot x=Split(root,pos); Droot y=Split(x.second,1); root=Merge(x.first,y.second); } int pre(int k){ int pos = Getkth(root, k); Droot x = Split(root, pos-1); Droot y = Split(x.second, 1); Treap *ans = y.first; root=Merge(Merge(x.first,ans),y.second); return ans->key; } int bak(int k){ int pos = Getkth(root, k+1); Droot x = Split(root, pos); Droot y = Split(x.second, 1); Treap *ans = y.first; root=Merge(Merge(x.first, ans), y.second); return ans->key; } int a[maxn],M,x,y; int main(){ scanf("%d",&M); while(M--){ int x, o; scanf("%d %d", &o, &x); switch(o){ case 1:Insert(x); break; case 2:Delete(x); break; case 3:printf("%d\n", Getkth(root, x)+1); break; case 4:printf("%d\n", Findkth(x)); break; case 5:printf("%d\n", pre(x)); break; case 6:printf("%d\n", bak(x)); break; } } }