BZOJ3224: Tyvj 1728 普通平衡树(无旋Treap/替罪羊)

来源:互联网 发布:appserv怎么进入mysql 编辑:程序博客网 时间:2024/05/29 10:26

传送门

题意:
平衡树的一系列操作。

题解:无旋Treap/替罪羊

作为一个用Splay水过无数道题的人,第一次写无旋Treap表示很慌。。

#include<bits/stdc++.h>using namespace std;typedef unsigned int uint;struct IO{    streambuf *ib,*ob;    inline void init(){        ios::sync_with_stdio(false);        cin.tie(NULL);cout.tie(NULL);        ib=cin.rdbuf();ob=cout.rdbuf();    }    inline int read(){        char ch=ib->sbumpc();int i=0,f=1;        while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}        while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();}        return i*f;    }    inline void W(long long x){        static int buf[50];        if(!x){ob->sputc('0');return;}        if(x<0){ob->sputc('-');x=-x;}        while(x)buf[++buf[0]]=x%10,x/=10;        while(buf[0])ob->sputc(buf[buf[0]--]+'0');    }    inline uint unit(){        static uint state0=23333;        state0^=state0<<13;        state0^=state0<<17;        state0^=state0>>5;        return state0;    }}io;const int Maxn=1e5+50;int n;struct node{    node *lc,*rc;    int sze,val;    uint pri;    node();    inline void upt(){        sze=lc->sze+rc->sze+1;    }}Pool[Maxn],*pool=Pool,*null=Pool;node::node():lc(null),rc(null){}typedef pair<node*,node*> pii;struct RecyclePool{    node *que[Maxn];    int tail;    inline node* newnode(int val){        static node* tmp;        tmp=(tail?que[tail--]:++pool);        tmp->lc=tmp->rc=null;        tmp->sze=1;tmp->val=val;tmp->pri=io.unit();        return tmp;    }}recyclepool;struct Treap{    node *rt;    Treap():rt(null){}    inline int getrank(int val){        node *tmp=rt;int k=0;        if(tmp==null)return 0;        while(tmp!=null){            if(tmp->val<val){k+=(tmp->lc->sze+1);tmp=tmp->rc;}            else tmp=tmp->lc;        }        return k;    }    inline node* merge(node *x,node *y){        if(x==null)return y;if(y==null)return x;        if(x->pri<y->pri){            x->rc=merge(x->rc,y);x->upt();            return x;        }        else{            y->lc=merge(x,y->lc);y->upt();            return y;        }    }    inline pii split(node *now,int k){        if(now==null)return pii(null,null);        if((now->lc->sze+1<=k)){            pii tr=split(now->rc,k-now->lc->sze-1);            now->rc=tr.first;now->upt();            return pii(now,tr.second);        }        else{            pii tr=split(now->lc,k);            now->lc=tr.second;now->upt();            return pii(tr.first,now);        }    }    inline void insert(int val){        int k=getrank(val);        pii tr=split(rt,k);        node *tmp=recyclepool.newnode(val);        rt=merge(merge(tr.first,tmp),tr.second);    }    inline void remove(int val){        int k=getrank(val);        pii tr1=split(rt,k);        pii tr2=split(tr1.second,1);        rt=merge(tr1.first,tr2.second);        recyclepool.que[++recyclepool.tail]=tr2.first;    }    inline int getkth(node *now,int k){        if(now->lc->sze+1<k)return getkth(now->rc,k-now->lc->sze-1);        else if(now->lc->sze+1==k)return now->val;        return getkth(now->lc,k);    }}treap;int main(){    io.init();n=io.read();    for(int i=1;i<=n;i++){        int op=io.read();        if(op==1){treap.insert(io.read());}        else if(op==2){treap.remove(io.read());}        else if(op==3){io.W(treap.getrank(io.read())+1);io.ob->sputc('\n');}        else if(op==4){io.W(treap.getkth(treap.rt,io.read()));io.ob->sputc('\n');}        else if(op==5){io.W(treap.getkth(treap.rt,treap.getrank(io.read())));io.ob->sputc('\n');}        else {io.W(treap.getkth(treap.rt,treap.getrank(io.read()+1)+1));io.ob->sputc('\n');}    }}

写完替罪羊发现不重构可以过。。于是正解原来是二叉搜索树???

#include<bits/stdc++.h>using namespace std;const int alpha=75;struct IO{    streambuf *ib,*ob;    inline void init(){        ios::sync_with_stdio(false);        cin.tie(NULL);cout.tie(NULL);        ib=cin.rdbuf();ob=cout.rdbuf();    }    inline int read(){        char ch=ib->sbumpc();int i=0,f=1;        while(!isdigit(ch)){if(ch=='-')f=-1;ch=ib->sbumpc();}        while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=ib->sbumpc();}        return i*f;    }    inline void W(int x){        static int buf[50];        if(!x){ob->sputc('0');ob->sputc('\n');return;}        if(x<0){ob->sputc('-');x=-x;}        while(x){buf[++buf[0]]=x%10;x/=10;}        while(buf[0]){ob->sputc(buf[buf[0]--]+'0');}        ob->sputc('\n');    }}io;const int Maxn=1e5+50;int n;struct node{    node *lc,*rc;    node():lc(NULL),rc(NULL){}    int sze,val,cnt;    inline void upt(){        sze=lc->sze+rc->sze+cnt;    }}Pool[Maxn],*pool=Pool,*null=Pool,*rt=null;inline node* newnode(int val){    ++pool;    pool->lc=pool->rc=null;    pool->sze=pool->cnt=1;pool->val=val;    return pool;}inline void insert_val(node*& now,int val,node**&p){    if(now==null){now=newnode(val);return;}    if(val<now->val)insert_val(now->lc,val,p);    else if(val>now->val)insert_val(now->rc,val,p);    else now->cnt++;    now->upt();    if(100*now->lc->sze>=now->sze*alpha||100*now->rc->sze>=now->sze*alpha)p=&now;}inline void erase_val(node*& now,int val,node **&p){    if(now->val==val)now->cnt--;    else if(now->val<val)erase_val(now->rc,val,p);    else erase_val(now->lc,val,p);    now->upt();    if(100*now->lc->sze>=now->sze*alpha||100*now->rc->sze>=now->sze*alpha)p=&now;}node* que[Maxn];int tail=0;inline void traval(node *p){    if(p->lc->sze)traval(p->lc);    if(p->cnt)que[++tail]=p;    if(p->rc->sze)traval(p->rc);}inline node* build(int l,int r){    static int cnt;    if(r<l)return null;    if(l==r){        que[l]->lc=que[l]->rc=null;        que[l]->sze=que[l]->cnt;        return que[l];    }    int mid=(l+r)>>1;    node* tmp=que[mid];    tmp->lc=build(l,mid-1);    tmp->rc=build(mid+1,r);    tmp->upt();    return tmp;}inline void rebuild(node *&p){    tail=0;traval(p);    int l=1,r=tail;    p=build(l,r);}inline void insert(node*& now,int val){    node **p=&null;    insert_val(now,val,p);    if(*p!=null)rebuild(*p);}inline void del(node*& now,int val){    node **p=&null;    erase_val(now,val,p);    if(*p!=null)rebuild(*p);}inline int getrank(int val){    int k=0;node *tmp=rt;    while(tmp!=null){        if(tmp->val<val)k+=tmp->lc->sze+tmp->cnt,tmp=tmp->rc;        else tmp=tmp->lc;    }    return k+1;}inline int getkth(node *now,int kth){    if(now->lc->sze>=kth)return getkth(now->lc,kth);    else if(now->lc->sze+now->cnt>=kth)return now->val;    else return getkth(now->rc,kth-now->lc->sze-now->cnt);}inline int getpre(int val){    node *tmp=rt;int last;    while(tmp!=null){        if(tmp->val>=val)tmp=tmp->lc;        else last=tmp->val,tmp=tmp->rc;    }    return last;}inline int getsuf(int val){    node *tmp=rt;int last;    while(tmp!=null){        if(tmp->val<=val)tmp=tmp->rc;        else last=tmp->val,tmp=tmp->lc;    }    return last;}int main(){    io.init();n=io.read();    for(int i=1;i<=n;i++){        int op=io.read();        if(op==1){            insert(rt,io.read());        }        else if(op==2){            del(rt,io.read());        }        else if(op==3){            io.W(getrank(io.read()));        }        else if(op==4){            io.W(getkth(rt,io.read()));        }        else if(op==5){            io.W(getkth(rt,getrank(io.read())-1));        }                   else io.W(getkth(rt,getrank(io.read()+1)));    }}
原创粉丝点击