C11【模板】可持久化平衡树
视频链接:269 可持久化平衡树_哔哩哔哩_bilibili
#include <iostream> using namespace std; const int N=500005; struct node{ int l,r; //左右儿子 int val; //树的权值 int rnd; //堆的随机值 int size; //子树大小 }tr[N*50]; int root[N],idx; void newnode(int &x,int v){ x = ++idx; tr[x].val=v; tr[x].rnd=rand(); tr[x].size=1; } void pushup(int p){ tr[p].size=tr[tr[p].l].size+tr[tr[p].r].size+1; } void split(int p,int v,int &x,int &y){ if(!p) {x=y=0; return;} if(tr[p].val<=v){ x = ++idx; tr[x]=tr[p]; split(tr[x].r,v,tr[x].r,y); pushup(x); } else{ y = ++idx; tr[y]=tr[p]; split(tr[y].l,v,x,tr[y].l); pushup(y); } } // int merge(int x,int y){ // if(!x||!y) return x+y; // int p = ++idx; // if(tr[x].rnd<tr[y].rnd){ // tr[p]=tr[x]; // tr[p].r=merge(tr[p].r,y); // pushup(p); return p; // } // else{ // tr[p]=tr[y]; // tr[p].l=merge(x,tr[p].l); // pushup(p); return p; // } // } int merge(int x,int y){ if(!x||!y) return x+y; if(tr[x].rnd<tr[y].rnd){ tr[x].r=merge(tr[x].r,y); pushup(x); return x; } else{ tr[y].l=merge(x,tr[y].l); pushup(y); return y; } } void insert(int &root,int v){ int x,y,z; split(root,v,x,y); newnode(z,v); root=merge(merge(x,z),y); } void del(int &root,int v){ int x,y,z; split(root,v,x,z); split(x,v-1,x,y); y=merge(tr[y].l,tr[y].r); root=merge(merge(x,y),z); } int getrank(int &root,int v){ int x,y; split(root,v-1,x,y); int ans=tr[x].size+1; root=merge(x,y); return ans; } int getval(int root,int v){ if(v==tr[tr[root].l].size+1) return tr[root].val; else if(v<=tr[tr[root].l].size) return getval(tr[root].l,v); else return getval(tr[root].r, v-tr[tr[root].l].size-1); } int getpre(int &root,int v){ int x,y,s,ans; split(root,v-1,x,y); if(!x)return -2147483647; s=tr[x].size; ans=getval(x,s); root=merge(x,y); return ans; } int getnxt(int &root,int v){ int x,y,ans; split(root,v,x,y); if(!y)return 2147483647; else ans=getval(y,1); root=merge(x,y); return ans; } int main(){ int n,ver,op,v; scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d%d%d",&ver,&op,&v); root[i]=root[ver]; if(op==1)insert(root[i],v); else if(op==2)del(root[i],v); else if(op==3)printf("%d\n",getrank(root[i],v)); else if(op==4)printf("%d\n",getval(root[i],v)); else if(op==5)printf("%d\n",getpre(root[i],v)); else printf("%d\n",getnxt(root[i],v)); } return 0; }