1439. Battle with You-Know-Who(splay树)

1439

路漫漫其修远兮~

手抄一枚splay树 长长的模版。。

关于spaly树的讲解   网上很多 随手贴一篇 貌似这题可以用什么bst啦 堆啦 平衡树啦 等等 这些本质都是有共同点的 查找、删除特别快 因为都有序 而且平衡~

看题很容易想到用线段树做 不过数太大了 离散化嘛 你肯定这么想 不过这题真不好离散 没想出来 只能硬啃这树那树了 

用splay树存下被删除的数 为原先的第几 再根据左边有多少个节点 右边有多少个节点 与询问的数比较大小  看他具体该在哪个位置 

每插入一个数  就把它旋到根节点 这样会节省时间 应该跟输入数据有关  我试了把询问时的那步旋转去掉 跑得死慢了

看代码吧 挺有意思的

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #define N 10010
  7 using namespace std;
  8 int n,m;
  9 struct splaytree
 10 {
 11     int size[N],ch[N][2],f[N],va[N];
 12     int root,top;
 13     inline void zig(int x)
 14     {
 15         int y = f[x],z = f[y];
 16         ch[y][1] = ch[x][0];f[ch[x][0]] = y;
 17         f[x] = z;ch[x][0] = y;f[y] = x;
 18         if(z) ch[z][ch[z][1]==y] = x;
 19         pushup(y);
 20     }
 21     inline void zag(int x)
 22     {
 23         int y = f[x],z = f[y];
 24         ch[y][0] = ch[x][1];f[ch[x][1]] = y;
 25         ch[x][1] = y;f[y] = x;f[x] = z;
 26         if(z) ch[z][ch[z][1]==y] = x;
 27         pushup(y);
 28     }
 29     inline void zigzig(int x)
 30     {
 31         int y = f[x],z = f[y],fz = f[z];
 32         ch[z][1] = ch[y][0]; f[ch[y][0]] = z;
 33         ch[y][1] = ch[x][0]; f[ch[x][0]] = y;
 34         f[z] = y;ch[y][0] = z;
 35         f[y] = x;ch[x][0] = y;
 36         f[x] = fz;
 37         if(fz) ch[fz][ch[fz][1]==z] = x;
 38         pushup(z);pushup(y);
 39     }
 40    inline void zagzag(int x){
 41 
 42         int y=f[x], z=f[y], fz=f[z];
 43 
 44         ch[z][0]=ch[y][1]; f[ch[y][1]]=z;
 45 
 46         ch[y][0]=ch[x][1]; f[ch[x][1]]=y;
 47 
 48         f[z] = y;ch[y][1] = z;
 49         f[y] = x;ch[x][1] = y;
 50         f[x] = fz;
 51         if(fz) ch[fz][ch[fz][1]==z] = x;
 52         pushup(z);pushup(y);
 53     }
 54     inline void zigzag(int x)
 55     {
 56         int y = f[x],z = f[y],fz = f[z];
 57         ch[y][1] = ch[x][0] ; f[ch[x][0]] = y;
 58         ch[z][0] = ch[x][1] ; f[ch[x][1]] = z;
 59         f[z] = x;ch[x][0] = y;
 60         f[y] = x;ch[x][1] = z;
 61         f[x] = fz;
 62         if(fz) ch[fz][ch[fz][1]==z] = x;
 63         pushup(y);pushup(z);
 64     }
 65     inline void zagzig(int x)
 66     {
 67         int y = f[x],z = f[y],fz = f[z];
 68         ch[y][0] = ch[x][1] ; f[ch[x][1]] = y;
 69         ch[z][1] = ch[x][0] ; f[ch[x][0]] = z;
 70         f[z] = x;ch[x][0] = z;
 71         f[y] = x;ch[x][1] = y;
 72         f[x] = fz;
 73         if(fz) ch[fz][ch[fz][1]==z] = x;
 74         pushup(y);pushup(z);
 75     }
 76     void splay(int x,int goal)
 77     {
 78         int y,z;
 79         while(f[x]!=goal)
 80         {
 81             if(f[f[x]]==goal)
 82             {
 83                 y = f[x];
 84                 if(ch[y][1]==x)
 85                 zig(x);
 86                 else
 87                 zag(x);
 88             }
 89             else
 90             {
 91                 y = f[x];z =f[y];
 92                 if(ch[z][1]==y)
 93                 {
 94                     if(ch[y][1]==x)
 95                     zigzig(x);
 96                     else
 97                     zagzig(x);
 98                 }
 99                 else
100                 {
101                     if(ch[y][0]==x)
102                     zagzag(x);
103                     else
104                     zigzag(x);
105                 }
106             }
107         }
108         pushup(x);
109         if(f[x]==0)
110         root = x;
111     }
112     inline void pushup(int x)
113     {
114         size[x] = size[ch[x][0]]+size[ch[x][1]]+1;
115     }
116     void init()
117     {
118         size[0] = ch[0][1] = ch[0][0] = f[0] = root = va[0] = top = 0;
119         insert(1000000001);
120     }
121     inline int newnode(int v)
122     {
123         size[++top] = 1;
124         ch[top][0] = ch[top][1] = f[top] = 0;
125         va[top] = v;
126         return top;
127     }
128     void insert(int v)
129     {
130         int r = root,x;
131         for(;;)
132         {
133             if(v>=va[r])
134             {
135                 if(ch[r][1])
136                 r = ch[r][1];
137                 else
138                 {
139                     x = newnode(v);
140                     ch[r][1] = x;
141                     f[x] = r;
142                     break;
143                 }
144             }
145             else
146             {
147                 if(ch[r][0])
148                 r = ch[r][0];
149                 else
150                 {
151                     x = newnode(v);
152                     ch[r][0] = x;
153                     f[x] = r;
154                     break;
155                 }
156             }
157         }
158         splay(x,0);
159     }
160     int query(int v)
161     {
162         int r = root,k = v,res = size[ch[root][0]];
163         for(;;)
164         {
165             if(k<va[r]-res)
166             {
167                 if(ch[r][0])
168                 {
169                     r = ch[r][0];
170                     res -= size[ch[r][1]]+1;
171                 }
172                 else
173                 {
174                     splay(r,0);
175                     return k+res;
176                 }
177             }
178             else
179             {
180                 if(ch[r][1])
181                 {
182                     r = ch[r][1];
183                     res += 1+size[ch[r][0]];
184                 }
185                 else
186                 {
187                     splay(r,0);
188                     return k+res+1;
189                 }
190             }
191         }
192     }
193 }tree;
194 int main()
195 {
196     int k;
197     char s[5];
198     tree.init();
199     scanf("%d%d",&n,&m);
200     while(m--)
201     {
202         scanf("%s%d",s,&k);
203         if(s[0]=='L')
204         printf("%d
",tree.query(k));
205         else
206         {
207             int x = tree.query(k);
208             tree.insert(x);
209         }
210     }
211     return 0;
212 }
View Code
原文地址:https://www.cnblogs.com/shangyu/p/3351452.html