【洛谷P3835】 【模板】可持久化平衡树
可持久化非旋转treap,真的是又好写又好调 ~
code:
#include <cstdio> #include <cstdlib> #include <algorithm> #define N 500007 #define lson t[x].ls #define rson t[x].rs #define inf 2147483647 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int tot; int cur; int Pr; int Nx; int rt[N]; struct node { int val; int size; int ls,rs; int ran; }t[N*50]; int newnode() { ++tot; t[tot].val=0; t[tot].size=1; t[tot].ran=rand(); t[tot].ls=t[tot].rs=0; return tot; } void pushup(int x) { t[x].size=t[lson].size+t[rson].size+1; } void split(int x,int v,int &l,int &r) { if(!x) { l=r=0; } else { int now=newnode(); t[now]=t[x]; if(t[x].val<=v) { l=now; split(rson,v,t[l].rs,r); } else { r=now; split(lson,v,l,t[r].ls); } pushup(now); } } int merge(int x,int y) { if(!x||!y) { return x+y; } int now=newnode(); if(rand()%(x+y)<x) { t[now]=t[x]; t[now].rs=merge(t[x].rs,y); } else { t[now]=t[y]; t[now].ls=merge(x,t[y].ls); } pushup(now); return now; } void Insert(int val) { int x=0; int y=0; split(rt[cur],val,x,y); int _new=newnode(); t[_new].val=val; _new=merge(x,_new); y=merge(_new,y); rt[cur]=y; } void Delete(int val) { int x=0; int y=0; int z=0; split(rt[cur],val,x,z); split(x,val-1,x,y); if(y) { y=merge(t[y].ls,t[y].rs); } y=merge(x,y); z=merge(y,z); rt[cur]=z; } int Rank(int val) { int x=0; int y=0; split(rt[cur],val-1,x,y); int re=t[x].size+1; rt[cur]=merge(x,y); return re; } void Pre(int x,int val) { if(!x) { return; } if(t[x].val<val) { Pr=max(Pr,t[x].val); Pre(rson,val); } else { Pre(lson,val); } } void Nxt(int x,int val) { if(!x) { return; } if(t[x].val>val) { Nx=min(Nx,t[x].val); Nxt(lson,val); } else { Nxt(rson,val); } } // 查询排名为 x 的数 int Num(int x,int kth) { if(t[lson].size+1==kth) { return t[x].val; } if(kth<=t[lson].size) { return Num(lson,kth); } else { return Num(rson,kth-t[lson].size-1); } } int main() { // setIO("input"); int i,j,m; scanf("%d",&m); for(cur=1;cur<=m;++cur) { int v,opt,x; scanf("%d%d%d",&v,&opt,&x); rt[cur]=rt[v]; if(opt==1) { Insert(x); } if(opt==2) { Delete(x); } if(opt==3) { printf("%d\n",Rank(x)); } if(opt==4) { printf("%d\n",Num(rt[cur],x)); } if(opt==5) { Pr=-inf; Pre(rt[cur],x); printf("%d\n",Pr); } if(opt==6) { Nx=inf; Nxt(rt[cur],x); printf("%d\n",Nx); } } return 0; }