平衡树模板集合

codesonic

2018-07-11 13:59:53

Personal

自己存着用的 # WBLT 210ms / 6792kb 长度:2.4KB ```cpp #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn=400010; const int ratio=5; int n,cnt,fa,root; int size[maxn],ls[maxn],rs[maxn],val[maxn]; inline void newnode(int &cur,int v){ cur=++cnt; size[cur]=1; val[cur]=v; } inline void copynode(int x,int y){ size[x]=size[y]; ls[x]=ls[y],rs[x]=rs[y]; val[x]=val[y]; } inline void merge(int l,int r){ size[++cnt]=size[l]+size[r]; val[cnt]=val[r]; ls[cnt]=l,rs[cnt]=r; } inline void rotate(int cur,bool flag){ if(flag){ merge(ls[cur],ls[rs[cur]]); ls[cur]=cnt; rs[cur]=rs[rs[cur]]; } else{ merge(rs[ls[cur]],rs[cur]); rs[cur]=cnt; ls[cur]=ls[ls[cur]]; } } inline void maintain(int cur){ if(size[ls[cur]]>size[rs[cur]]*ratio) rotate(cur,0); else if(size[rs[cur]]>size[ls[cur]]*ratio) rotate(cur,1); } inline void pushup(int cur){ if(!size[ls[cur]])return ; size[cur]=size[ls[cur]]+size[rs[cur]]; val[cur]=val[rs[cur]]; } inline int minn(int a,int b){ return a<b?a:b; } inline int maxx(int a,int b){ return a>b?a:b; } inline void insert(int cur,int x){ if(size[cur]==1){ newnode(ls[cur],minn(x,val[cur])); newnode(rs[cur],maxx(x,val[cur])); pushup(cur); return ; } maintain(cur); insert(x>val[ls[cur]]?rs[cur]:ls[cur],x); pushup(cur); } inline void erase(int cur,int x){ if(size[cur]==1){ cur= ls[fa]==cur?rs[fa]:ls[fa]; copynode(fa,cur); return ; } maintain(cur); fa=cur; erase(x>val[ls[cur]]?rs[cur]:ls[cur],x); pushup(cur); } inline int find(int cur,int x){ if(size[cur]==x) return val[cur]; maintain(cur); if(x>size[ls[cur]]) return find(rs[cur],x-size[ls[cur]]); return find(ls[cur],x); } inline int rnk(int cur,int x){ if(size[cur]==1) return 1; maintain(cur); if(x>val[ls[cur]]) return rnk(rs[cur],x)+size[ls[cur]]; return rnk(ls[cur],x); } int main(){ scanf("%d",&n); newnode(root,(1<<30)); while(n--){ int s,x; scanf("%d%d",&s,&x); if(s==1)insert(root,x); if(s==2)erase(root,x); if(s==3)printf("%d\n",rnk(root,x)); if(s==4)printf("%d\n",find(root,x)); if(s==5)printf("%d\n",find(root,rnk(root,x)-1)); if(s==6)printf("%d\n",find(root,rnk(root,x+1))); } return 0; } ``` # 旋转treap 252ms / 3.2MB 长度:2.35KB ``` #include<cstdio> #include<iostream> #include<algorithm> #define maxn 100005 #define INF (1<<30) int n; struct treap{ int l[maxn],r[maxn],val[maxn],rnd[maxn],size[maxn],w[maxn]; int sz,ans,rt; inline void pushup(int x){ size[x]=size[l[x]]+size[r[x]]+w[x]; } void lrotate(int &k){ int t=r[k]; r[k]=l[t]; l[t]=k; size[t]=size[k]; pushup(k); k=t; } void rrotate(int &k){ int t=l[k]; l[k]=r[t]; r[t]=k; size[t]=size[k]; pushup(k); k=t; } void insert(int &k,int x){ if(!k){ sz++;k=sz;size[k]=1;w[k]=1;val[k]=x; rnd[k]=rand();return; } size[k]++; if(val[k]==x){ w[k]++; } else if(val[k]<x){ insert(r[k],x); if(rnd[r[k]]<rnd[k]) lrotate(k); } else { insert(l[k],x); if(rnd[l[k]]<rnd[k]) rrotate(k); } } void del(int &k,int x){ if(!k)return ; if(val[k]==x){ if(w[k]>1){ w[k]--; size[k]--; return ; } if(l[k]==0||r[k]==0) k=l[k]+r[k]; else if(rnd[l[k]]<rnd[r[k]]){ rrotate(k); del(k,x); } else{ lrotate(k); del(k,x); } } else if(val[k]<x){ size[k]--; del(r[k],x); } else { size[k]--; del(l[k],x); } } int queryrank(int k,int x){ if(!k) return 0; if(val[k]==x) return size[l[k]]+1; else if(x>val[k]){ return size[l[k]]+w[k]+queryrank(r[k],x); } else return queryrank(l[k],x); } int querynum(int k,int x){ if(!k) return 0; if(x<=size[l[k]]) return querynum(l[k],x); else if(x>size[l[k]]+w[k]) return querynum(r[k],x-size[l[k]]-w[k]); else return val[k]; } void querypre(int k,int x){ if(!k) return ; if(val[k]<x) ans=k,querypre(r[k],x); else querypre(l[k],x); } void querysub(int k,int x){ if(!k) return ; if(val[k]>x) ans=k,querysub(l[k],x); else querysub(r[k],x); } }T; int main() { scanf("%d",&n); int opt,x; for(int i=1;i<=n;i++){ scanf("%d%d",&opt,&x); if(opt==1)T.insert(T.rt,x); else if(opt==2)T.del(T.rt,x); else if(opt==3){ printf("%d\n",T.queryrank(T.rt,x)); } else if(opt==4){ printf("%d\n",T.querynum(T.rt,x)); } else if(opt==5){ T.ans=0; T.querypre(T.rt,x); printf("%d\n",T.val[T.ans]); } else if(opt==6){ T.ans=0; T.querysub(T.rt,x); printf("%d\n",T.val[T.ans]); } } return 0; } ``` # fhq treap 572ms / 2.65MB 长度:2.13KB C++ ```cpp #include<cstdio> #include<algorithm> using namespace std; const int maxn=500010; int n,m,x,y,z,tot,opt; struct fhq_treap{ int rnd[maxn],sum[maxn],size[maxn],ls[maxn],rs[maxn],root,tmp; inline void build(int &x,int delta){ rnd[x=++tot]=rand()<<15|rand(); sum[x]=delta; size[x]=1; } inline void up(int x){ if(!x) return ; size[x]=size[ls[x]]+size[rs[x]]+1; } void merge(int &x,int l,int r){ if(!l||!r) x=l+r; else if(rnd[l]<rnd[r]) x=l,merge(rs[x],rs[x],r),up(x); else x=r,merge(ls[x],l,ls[x]),up(x); } void split(int x,int &l,int &r,int k){ if(!k) l=0,r=x; else if(k==size[x]) l=x,r=0; else if(k<=size[ls[x]]) r=x,split(ls[x],l,ls[x],k),up(x); else l=x,split(rs[x],rs[x],r,k-size[ls[x]]-1),up(x); } int rank(int x,int w){ if(!x) return 0; if(sum[x]>=w) return rank(ls[x],w); return rank(rs[x],w)+size[ls[x]]+1; } inline void insert(int delta){ int x,y,rk=rank(root,delta); split(root,x,y,rk); build(tmp,delta); merge(x,x,tmp); merge(root,x,y); } inline void del(int delta){ int x,y,z,rk=rank(root,delta)+1; split(root,x,y,rk); split(x,x,z,rk-1); merge(root,x,y); } inline int find(int delta) { int x,y,z,ans; split(root,x,y,delta); split(x,z,x,delta-1); ans=sum[x]; merge(x,z,x); merge(root,x,y); return ans; } inline int pre(int delta){ int x,y,z,ans,rk=rank(root,delta); split(root,x,y,rk); split(x,z,x,rk-1); ans=sum[x]; merge(x,z,x); merge(root,x,y); return ans; } inline int sub(int delta){ int x,y,z,ans,rk=rank(root,delta+1); split(root,x,y,rk+1); split(x,z,x,rk); ans=sum[x]; merge(x,z,x); merge(root,x,y); return ans; } }T; int main() { srand(19260817); scanf("%d",&n); T.rnd[0]=T.sum[0]=(1<<30); while(n--){ int opt; scanf("%d%d",&opt,&x); if(opt==1) T.insert(x); else if(opt==2) T.del(x); else if(opt==3)printf("%d\n",T.rank(T.root,x)+1); else if(opt==4)printf("%d\n",T.find(x)); else if(opt==5)printf("%d\n",T.pre(x)); else printf("%d\n", T.sub(x)); } } ```