luogu P3835 【模板】可持久化平衡树
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; const int maxn=500009; const int oo=2147483647; int T; int nn=0; int ch[maxn*50][2]={0},siz[maxn*50]={0},pri[maxn*50]={0},ky[maxn*50]={0}; int root[maxn]={0}; void pushup(int x){ siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1; } int NewNode(int val){ int x=++nn; ky[x]=val; siz[x]=1; pri[x]=rand(); return x; } int CopyNode(int y){ int x=++nn; ch[x][0]=ch[y][0]; ch[x][1]=ch[y][1]; pri[x]=pri[y]; siz[x]=siz[y]; ky[x]=ky[y]; return x; } int Mer(int x,int y){ if((!x)||(!y))return x+y; if(pri[x]<pri[y]){ int p=CopyNode(x); ch[p][1]=Mer(ch[p][1],y); pushup(p); return p; }else{ int p=CopyNode(y); ch[p][0]=Mer(x,ch[p][0]); pushup(p); return p; } } void Split(int now,int k,int &x,int &y){ if(!now){ x=y=0; }else{ if(ky[now]<=k){ x=CopyNode(now); Split(ch[x][1],k,ch[x][1],y); pushup(x); }else{ y=CopyNode(now); Split(ch[y][0],k,x,ch[y][0]); pushup(y); } } } void Del(int &rt,int val){ int x,y,z; Split(rt,val,x,z); Split(x,val-1,x,y); y=Mer(ch[y][0],ch[y][1]); rt=Mer(Mer(x,y),z); } void Ins(int &rt,int val){ int x,y,z; Split(rt,val,x,y); rt=Mer(Mer(x,NewNode(val)),y); } int Kth(int x,int k){ while(x){ int l=ch[x][0]; if(k<=siz[l]){ x=ch[x][0]; }else if(k>siz[l]+1){ k-=(siz[l]+1); x=ch[x][1]; }else{ return ky[x]; } } } int Rank(int x,int val){ int ret=0; while(x){ if(ky[x]<val){ ret+=siz[ch[x][0]]+1; x=ch[x][1]; }else if(ky[x]>val){ x=ch[x][0]; }else{ ret+=siz[ch[x][0]];break; } } return ret+1; } int Getpre(int x,int val){ int ret=oo; while(x){ if(ky[x]<val){ ret=ky[x]; x=ch[x][1]; }else{ x=ch[x][0]; } } return ret; } int Getsuc(int x,int val){ int ret=-oo; while(x){ if(ky[x]>val){ ret=ky[x]; x=ch[x][0]; }else{ x=ch[x][1]; } } return ret; } void check(int x){ if(ch[x][0])check(ch[x][0]); cout<<ky[x]<<' '; if(ch[x][1])check(ch[x][1]); } int main(){ scanf("%d",&T); for(int i=1;i<=T;++i){ int opty,pre,a; scanf("%d%d%d",&pre,&opty,&a); root[i]=root[pre]; if(opty==1)Ins(root[i],a); if(opty==2)Del(root[i],a); if(opty==3)printf("%d\n",Rank(root[i],a)); if(opty==4)printf("%d\n",Kth(root[i],a)); if(opty==5)printf("%d\n",Getpre(root[i],a)); if(opty==6)printf("%d\n",Getsuc(root[i],a)); // check(root[i]); // cout<<endl; } return 0; }
致歉:笔者已经意识到这是一篇几乎没有价值的文章,给您的阅读带来不好的体验,并且干扰了您的搜索环境,非常抱歉!