BZOJ3224 Tyvj 1728 普通平衡树

splay,各种初级操作。

一个麻烦的地方就是可以有重复数字,可以用想办法标记下来,如果用数组的话需要开的空间太大,可以用map标记,虽然慢了点。

还是第一次写着个东西,有一个地方写了很多次每次都错,就是insert的时候,最后把刚加进来的节点伸展到根节点,应该是spaly(tot,0);每次都写成splay(x,0)..

 

 

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <map>
  4 using namespace std;
  5 const int maxn = 100005;
  6 int fa[maxn],son[2][maxn],val[maxn],siz[maxn];
  7 int root,tot,cnt;
  8 map<int,int>mp;
  9 void rota(int w,int x){
 10     int y = fa[x];
 11     son[!w][y] = son[w][x];
 12     if(son[w][x])fa[son[w][x]] = y;
 13     fa[x] = fa[y];
 14     if(fa[y])son[y==son[1][fa[y]]][fa[y]] = x;
 15     fa[y] = x;
 16     son[w][x] = y;
 17     siz[y] = siz[y]-siz[x]+siz[son[!w][y]];
 18     siz[x] = siz[x]+siz[y]-siz[son[!w][y]];
 19 }
 20 void splay(int x,int y){
 21     while(fa[x]!=y){
 22         if(fa[fa[x]]==y)rota(x==son[0][fa[x]],x);
 23         else {
 24             int w = fa[x]==son[0][fa[fa[x]]];
 25             if(x==son[w][x]){
 26                 rota(!w,x);
 27                 rota(w,x);
 28             }
 29             else {
 30                 rota(w,fa[x]);
 31                 rota(w,x);
 32             }
 33         }
 34     }
 35     if(y==0)root = x;
 36 }
 37 void Ins(int v){
 38     int x = root;
 39     while(1){
 40         siz[x]++;
 41         if(v==val[x]){splay(x,0);return;}
 42         if(v<val[x]){
 43             if(son[0][x])x = son[0][x];
 44             else break;
 45         }
 46         else {
 47             if(son[1][x])x = son[1][x];
 48             else break;
 49         }
 50     }
 51     fa[++tot] = x;
 52     val[tot] = v;
 53     siz[tot] = 1;
 54     if(v<val[x])son[0][x] = tot;
 55     else son[1][x] = tot;
 56     splay(tot,0);///duoshou
 57 }
 58 int Find(int v){
 59     int x = root;
 60     while(x!=0){
 61         if(v==val[x])break;
 62         if(v<val[x])x = son[0][x];
 63         else x = son[1][x];
 64     }
 65     splay(x,0);
 66     return x;
 67 }
 68 void Del(int v){
 69     int x = Find(v),y = son[0][x],z = son[1][x];
 70     while(son[1][y])y = son[1][y];
 71     while(son[0][z])z = son[0][z];
 72 
 73     if(y==0&&z==0){
 74         siz[x]--;
 75         if(!siz[x])root = 0;
 76         return;
 77     }
 78     if(y)splay(y,0);
 79     if(z)splay(z,y);
 80     if(y==0){
 81         siz[x]--;siz[z]--;
 82         if(!siz[x])son[0][z] = 0;
 83         return;
 84     }
 85     if(z==0){
 86         siz[x]--;siz[y]--;
 87         if(!siz[x])son[1][y] = 0;
 88         return;
 89     }
 90     siz[x]--;siz[y]--;siz[z]--;
 91     if(!siz[x])son[0][z] = 0;
 92 }
 93 int getRank(int v){
 94     int x = Find(v);
 95     return siz[son[0][x]]+1;
 96 }
 97 int getV(int k){
 98     int x = root;
 99     while(!(k>siz[son[0][x]]&&k<=siz[son[0][x]]+mp[val[x]])){
100         if(k<=siz[son[0][x]])x = son[0][x];
101         else {
102             k-=(siz[son[0][x]]+mp[val[x]]);
103             x = son[1][x];
104         }
105     }
106     return val[x];
107 }
108 int getPre(int v){
109     int x = son[0][Find(v)];
110     while(son[1][x])x = son[1][x];
111     return val[x];
112 }
113 int getNext(int v){
114     int x = son[1][Find(v)];
115     while(son[0][x])x = son[0][x];
116     return val[x];
117 }
118 int main()
119 {
120     //freopen("in.txt","r",stdin);
121     int n,ans;scanf("%d",&n);
122     for(int i = 1;i<=n;++i){
123         int op,x;scanf("%d%d",&op,&x);
124         if(op==1){
125             if(cnt==0){
126                 root = ++tot;
127                 siz[tot] = 1;
128                 val[tot] = x;
129             }
130             else Ins(x);
131             mp[x]++;cnt++;
132         }
133         else if(op==2){
134             if(mp[x]){Del(x);mp[x]--;cnt--;}
135         }
136         else if(op==3){
137             printf("%d\n",getRank(x));
138         }
139         else if(op==4){
140             printf("%d\n",getV(x));
141         }
142         else if(op==5){
143             if(mp[x])ans = getPre(x);
144             else {
145                 Ins(x);
146                 ans = getPre(x);
147                 Del(x);
148             }
149             printf("%d\n",ans);
150         }
151         else {
152             if(mp[x])ans = getNext(x);
153             else {
154                 Ins(x);
155                 ans = getNext(x);
156                 Del(x);
157             }
158             printf("%d\n",ans);
159         }
160     }
161     return 0;
162 }

 

posted on 2015-08-05 17:42  round_0  阅读(141)  评论(0编辑  收藏  举报

导航