[模板]普通平衡樹
阿新 • • 發佈:2018-01-22
clas tdi names class using update rand 平衡樹 urn
原題鏈接:https://www.luogu.org/problemnew/show/3369
一個平衡樹的板子
代碼來自於黃學長,個人碼風
#include<cstdio> #include<cstdlib> #include<iostream> using namespace std; void read(int &y) { y=0;char x=getchar(); while(x<‘0‘||x>‘9‘) x=getchar(); while(x>=‘0‘&&x<=‘9‘) { y=y*10+x-‘0‘; x=getchar(); } } struct treap { int l,r,v,size,rnd,w; }tr[100005]; int n,cnt,rot,op,m,ans; void update(int k) { tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w; } void rturn(int &k) { int t=tr[k].l; tr[k].l=tr[t].r;tr[t].r=k; tr[t].size=tr[k].size; update(k);k=t; } void lturn(int &k) { int t=tr[k].r; tr[k].r=tr[t].l;tr[t].l=k; tr[t].size=tr[k].size; update(k);k=t; } void insert(int &k,int x) { if(k==0) { cnt++;k=cnt; tr[k].size=tr[k].w=1; tr[k].v=x;tr[k].rnd=rand(); return; } tr[k].size++; if(tr[k].v==x) tr[k].w++; else if(x>tr[k].v) { insert(tr[k].r,x); if(tr[tr[k].r].rnd<tr[k].rnd) lturn(k); } else { insert(tr[k].l,x); if(tr[tr[k].l].rnd<tr[k].rnd) rturn(k); } } void del(int &k,int x) { if(k==0) return; if(tr[k].v==x) { if(tr[k].w>1) { tr[k].w--; tr[k].size--; return; } if(tr[k].l*tr[k].r==0) k=tr[k].l+tr[k].r; else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd) { rturn(k); del(k,x); } else { lturn(k); del(k,x); } } else if(x>tr[k].v) { tr[k].size--; del(tr[k].r,x); } else { tr[k].size--; del(tr[k].l,x); } } int rank(int k,int x) { if(k==0) return 0; if(tr[k].v==x) return tr[tr[k].l].size+1; else if(x>tr[k].v) return tr[tr[k].l].size+tr[k].w+rank(tr[k].r,x); else return rank(tr[k].l,x); } int num(int k,int x) { if(k==0) return 0; if(x<=tr[tr[k].l].size) return num(tr[k].l,x); else if(x>tr[tr[k].l].size+tr[k].w) return num(tr[k].r,x-tr[tr[k].l].size-tr[k].w); else return tr[k].v; } void pro(int k,int x) { if(k==0) return; if(tr[k].v<x) { ans=k; pro(tr[k].r,x); } else pro(tr[k].l,x); } void sub(int k,int x) { if(k==0) return; if(tr[k].v>x) { ans=k; sub(tr[k].l,x); } else sub(tr[k].r,x); } int main() { read(n); while(n--) { scanf("%d %d",&op,&m); if(op==1) insert(rot,m); if(op==2) del(rot,m); if(op==3) printf("%d\n",rank(rot,m)); if(op==4) printf("%d\n",num(rot,m)); if(op==5) { ans=0; pro(rot,m); printf("%d\n",tr[ans].v); } if(op==6) { ans=0; sub(rot,m); printf("%d\n",tr[ans].v); } } return 0; }
[模板]普通平衡樹