T105331 【模板】普通平衡树(Treap)
作者:互联网
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int SIZE=100010; struct Treap{ int l,r; int val,dat; int size,cnt; }a[SIZE]; int n,root,tot,INF=0x7fffffff; int New(int val){ a[++tot].val=val; a[tot].dat=rand(); a[tot].size=a[tot].cnt=1; return tot; } void updata(int p){ a[p].size=a[a[p].l].size+a[a[p].r].size+a[p].cnt; } void build(){ New(-INF),New(INF); root=1,a[1].r=2; updata(1); } void zig(int &p){ int q=a[p].l; a[p].l=a[q].r,a[q].r=p,p=q; updata(p),updata(a[p].r); } void zag(int &p){ int q=a[p].r; a[p].r=a[q].l,a[q].l=p,p=q; updata(p),updata(a[p].l); } int getRankByVal(int p,int val){ if(a[p].val==val)return a[a[p].l].size+1; if(a[p].val>val)return getRankByVal(a[p].l,val); return getRankByVal(a[p].r,val)+a[a[p].l].size+a[p].cnt; } int getValByRank(int p,int rank){ if(a[a[p].l].size>=rank)return getValByRank(a[p].l,rank); if(a[a[p].l].size+a[p].cnt>=rank)return a[p].val; return getValByRank(a[p].r,rank-a[a[p].l].size-a[p].cnt); } void add(int &p,int val){ if(p==0){ p=New(val),updata(p); return; } if(a[p].val==val){ a[p].cnt++,updata(p); return; } if(a[p].val>val){ add(a[p].l,val),updata(p); if(a[a[p].l].dat>a[p].dat)zig(p); }else{ add(a[p].r,val),updata(p); if(a[a[p].r].dat>a[p].dat)zag(p); } updata(p); } void remove(int &p,int val){ if(p==0)return; if(a[p].val==val){ if(a[p].cnt>1){ a[p].cnt--,updata(p); return; } if(a[p].l||a[p].r){ if(a[p].r==0||a[a[p].l].dat>a[a[p].r].dat){ zig(p),remove(a[p].r,val); }else{ zag(p),remove(a[p].l,val); } updata(p); }else p=0; return; } remove(a[p].val>val?a[p].l:a[p].r,val); updata(p); } int getPre(int val){ int ans=1,p=root; while(p){ if(a[p].val==val){ if(a[p].l){ p=a[p].l; while(a[p].r)p=a[p].r; ans=p; } } if(a[p].val<val&&a[p].val>a[ans].val)ans=p; p=a[p].val>val?a[p].l:a[p].r; } return a[ans].val; } int getNext(int val){ int ans=2,p=root; while(p){ if(a[p].val==val){ if(a[p].r){ p=a[p].r; while(a[p].l)p=a[p].l; ans=p; } break; } if(a[p].val>val&&a[p].val<a[ans].val)ans=p; p=a[p].val>val?a[p].l:a[p].r; } return a[ans].val; } int main(){ build(); cin>>n; while(n--){ int opt,x; scanf("%d%d",&opt,&x); switch(opt){ case 1: add(root,x); break; case 2: remove(root,x); break; case 3: printf("%d\n",getRankByVal(root,x)-1); break; case 4: printf("%d\n",getValByRank(root,x+1)); break; case 5: printf("%d\n",getPre(x)); break; case 6: printf("%d\n",getNext(x)); break; } } }
标签:cnt,return,val,int,updata,Treap,T105331,模板,size 来源: https://www.cnblogs.com/zbsy-wwx/p/11742361.html