P3369 【模板】普通平衡树 替罪羊树解法
作者:互联网
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define lc ch[p][0] #define rc ch[p][1] using namespace std; const int N=100010; const int inf=0x3f3f3f3f; const double alpha=0.75; int n,m; int rt=1,tot=1; int loc[N],sum; int ch[N][2],fa[N]; double siz[N]; int val[N]; inline void pushup(int p){ siz[p]=siz[lc]+siz[rc]+1; } inline bool banlc(int p){ if(siz[lc]>siz[p]*alpha) return 0; if(siz[rc]>siz[p]*alpha) return 0; return 1; } void build(int &p,int L,int R){ if(L>R){ p=0; return; } int mid=(L+R)>>1; p=loc[mid]; build(lc,L,mid-1); build(rc,mid+1,R); if(lc) fa[lc]=p; if(rc) fa[rc]=p; pushup(p); } void DFS(int p){ if(!p) return; if(lc) DFS(lc); loc[++sum]=p; if(rc) DFS(rc); } void rebuild(int p){ sum=0; DFS(p); int f0=fa[p]; bool b=(ch[f0][0]!=p); int cur; build(cur,1,sum); fa[cur]=f0; ch[f0][b]=cur; if(p==rt) rt=cur; } void ins(int v){ int p=rt,cur=++tot; siz[cur]=1; val[cur]=v; bool b; while(1){ siz[p]++; b=(v>=val[p]); if(ch[p][b]) p=ch[p][b]; else{ ch[p][b]=cur; fa[cur]=p; break; } } int pos=0; for(int i=cur;i;i=fa[i]){ if(!banlc(i)) pos=i; } if(pos) rebuild(pos); } inline int getpos(int p,int v){ while(1){ if(val[p]==v) return p; if(v>val[p]) p=rc; else p=lc; } } inline void del(int v){ int p=getpos(rt,v); if(lc&&rc){ int cur=lc; while(ch[cur][1]) cur=ch[cur][1]; val[p]=val[cur]; p=cur; } int son=lc?lc:rc; int f0=fa[p]; bool b=ch[f0][0]!=p; ch[f0][b]=son; fa[son]=f0; for(int i=fa[p];i;i=fa[i]) siz[i]--; if(p==rt) rt=son; } inline int getrank(int p,int v){ int ret=0; while(p){ if(v>val[p]) ret+=siz[lc]+1,p=rc; else p=lc; } return ret; } inline int kth(int p,int k){ while(1){ if(k<=siz[lc]) p=lc; else if(k==siz[lc]+1) return p; else k-=siz[lc],k--,p=rc; } } inline int getpre(int p,int v){ int ret=-inf; while(p){ if(v>val[p]) ret=max(ret,val[p]),p=rc; else p=lc; } return ret; } inline int getsuc(int p,int v){ int ret=inf; while(p){ if(v<val[p]) ret=min(ret,val[p]),p=lc; else p=rc; } return ret; } int main(){ scanf("%d",&n); siz[rt]=1; val[rt]=-inf; int op,x; while(n--){ scanf("%d%d",&op,&x); if(op==1) ins(x); if(op==2) del(x); if(op==3) printf("%d\n",getrank(rt,x)); if(op==4) printf("%d\n",val[kth(rt,x+1)]); if(op==5) printf("%d\n",getpre(rt,x)); if(op==6) printf("%d\n",getsuc(rt,x)); } return 0; }
标签:ch,cur,int,siz,替罪羊,P3369,rc,模板,lc 来源: https://www.cnblogs.com/smghj/p/16028906.html