【模板】 普通平衡树

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 }
View Code

猜你喜欢

转载自www.cnblogs.com/xiaobuxie/p/11308187.html