【模板】 普通平衡树
emm这两天终于来学学平衡树了,自己没有板,只能靠网上大佬的板来学了,感觉大佬打的板挺好的。
原文:https://blog.csdn.net/a_comme_amour/article/details/79382104
评测的是洛谷:https://www.luogu.org/record/22239881
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+8; 4 int ch[N][2],f[N],siz[N],cnt[N],val[N]; 5 int sz,rt; 6 inline void clear(int x){ 7 ch[x][0]=ch[x][1]=f[x]=siz[x]=cnt[x]=val[x]=0; 8 } 9 inline bool get(int x){ 10 return ch[f[x]][1]==x; 11 } 12 inline void update(int x){ 13 if(x){ 14 siz[x]=cnt[x]; 15 if(ch[x][0]) siz[x]+=siz[ch[x][0]]; 16 if(ch[x][1]) siz[x]+=siz[ch[x][1]]; 17 } 18 } 19 inline void rotate(int x){ 20 int fa=f[x],ffa=f[fa],which=get(x); 21 ch[fa][which]=ch[x][which^1];f[ch[fa][which]]=fa; 22 ch[x][which^1]=fa;f[fa]=x; 23 f[x]=ffa; 24 if(ffa) ch[ffa][ch[ffa][1]==fa]=x; 25 update(fa);update(x); 26 } 27 inline void splay(int x){ 28 for(int fa;fa=f[x];rotate(x)){ 29 if(f[fa]){ 30 rotate( (get(x)==get(fa)) ? fa : x ); 31 } 32 } 33 rt=x; 34 } 35 inline void ins(int x){ 36 if(!rt){ 37 ++sz;ch[sz][0]=ch[sz][1]=f[sz]=0; 38 rt=sz;siz[sz]=cnt[sz]=1;val[sz]=x; 39 return; 40 } 41 int now=rt,fa=0; 42 while(1){ 43 if(x==val[now]){ 44 ++cnt[now]; 45 update(now);update(fa); 46 splay(now); 47 return; 48 } 49 fa=now; 50 now=ch[now][val[now]<x]; 51 if(!now){ 52 ++sz; 53 ch[sz][0]=ch[sz][1]=0; 54 f[sz]=fa; 55 siz[sz]=cnt[sz]=1; 56 ch[fa][val[fa]<x]=sz; 57 val[sz]=x; 58 update(fa); 59 splay(sz); 60 return; 61 } 62 } 63 } 64 inline int rnk(int x){ 65 int now=rt,ans=0; 66 while(1){ 67 if(x<val[now]) now=ch[now][0]; 68 else{ 69 ans+=(ch[now][0]?siz[ch[now][0]]:0); 70 if(x==val[now]){ 71 splay(now); 72 return ans+1; 73 } 74 ans+=cnt[now]; 75 now=ch[now][1]; 76 } 77 } 78 } 79 inline int kth(int x){ 80 int now=rt; 81 while(1){ 82 if(ch[now][0] && x<=siz[ch[now][0]]) now=ch[now][0]; 83 else{ 84 int tem=(ch[now][0]?siz[ch[now][0]]:0)+cnt[now]; 85 if(x<=tem) return val[now]; 86 x-=tem;now=ch[now][1]; 87 } 88 } 89 } 90 inline int pre(){ 91 int now=ch[rt][0]; 92 while(ch[now][1]) now=ch[now][1]; 93 return now; 94 } 95 inline int nex(){ 96 int now=ch[rt][1]; 97 while(ch[now][0]) now=ch[now][0]; 98 return now; 99 } 100 inline void del(int x){ 101 rnk(x); 102 if(cnt[rt]>1){--cnt[rt]; update(rt); return;} 103 if(!ch[rt][0] && !ch[rt][1]) {clear(rt); rt=0; return;} 104 if(!ch[rt][0]){ 105 int oldrt=rt; rt=ch[rt][1]; f[rt]=0; 106 clear(oldrt); return; 107 } 108 if(!ch[rt][1]){ 109 int oldrt=rt; rt=ch[rt][0]; f[rt]=0; 110 clear(oldrt); return; 111 } 112 int lebig=pre(),oldrt=rt; 113 splay(lebig); 114 ch[rt][1]=ch[oldrt][1]; 115 f[ch[oldrt][1]]=rt; 116 clear(oldrt); 117 update(rt); 118 } 119 int main(){ 120 int n;scanf("%d",&n); 121 for(int i=1;i<=n;++i){ 122 int op,x;scanf("%d %d",&op,&x); 123 switch(op){ 124 case 1:ins(x);break; 125 case 2:del(x);break; 126 case 3:printf("%d\n",rnk(x));break; 127 case 4:printf("%d\n",kth(x));break; 128 case 5:ins(x);printf("%d\n",val[pre()]);del(x);break; 129 case 6:ins(x);printf("%d\n",val[nex()]);del(x);break; 130 } 131 } 132 return 0; 133 }