POJ 3580-SuperMemo-splay树

很完整的splay操作。做了这题就可以当板子用了。

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4 
  5 using namespace std;
  6 
  7 #define Key_value ch[ch[root][1] ][0]
  8 
  9 const int maxn = 5e5+10;
 10 const int INF = 0x3f3f3f3f;
 11 
 12 int pre[maxn],ch[maxn][2],key[maxn],sz[maxn];
 13 int root,tot1;
 14 int rev[maxn],mi[maxn],add[maxn];
 15 int s[maxn],tot2;
 16 int a[maxn];
 17 int n,q;
 18 
 19 void Treavel(int x)
 20 {
 21     if(x)
 22     {
 23         Treavel(ch[x][0]);
 24         printf("结点:%2d: 左儿子 %2d 右儿子 %2d 父结点 %2d key=%2d size= %2d mi=%2d add=%2d\n",x,ch[x][0],ch[x][1],pre[x],key[x],sz[x],mi[x],add[x]);
 25         Treavel(ch[x][1]);
 26     }
 27 }
 28 void debug()
 29 {
 30     printf("root:%d\n",root);
 31     Treavel(root);
 32 }
 33 //
 34 
 35 void NewNode(int &r,int father,int k)
 36 {
 37     if(tot2) r = s[tot2--];
 38     else r = ++tot1;
 39     pre[r] = father;
 40     ch[r][0] = ch[r][1] = 0;
 41     key[r] = k;
 42     mi[r] = k;
 43     rev[r] = add[r] = 0;
 44     sz[r] = 1;
 45 }
 46 
 47 void Update_add(int r,int c)
 48 {
 49     if(!r) return ;
 50     key[r] += c;
 51     mi[r] += c;
 52     add[r] += c;
 53 }
 54 
 55 void Update_rev(int r)
 56 {
 57     if(!r) return ;
 58     swap(ch[r][0],ch[r][1]);
 59     rev[r] ^= 1;
 60 }
 61 
 62 void push_up(int r)
 63 {
 64     int lson = ch[r][0],rson = ch[r][1];
 65     sz[r] = sz[lson] + sz[rson] + 1;
 66     mi[r] = min(min(mi[lson],mi[rson]),key[r]);
 67 }
 68 
 69 void push_down(int r)
 70 {
 71     if(rev[r])
 72     {
 73         Update_rev(ch[r][0]);
 74         Update_rev(ch[r][1]);
 75         rev[r] = 0;
 76     }
 77     if(add[r])
 78     {
 79         Update_add(ch[r][0],add[r]);
 80         Update_add(ch[r][1],add[r]);
 81         add[r] = 0;
 82     }
 83 }
 84 
 85 void Build(int &x,int l,int r,int father)
 86 {
 87     if(l>r) return ;
 88     int mid = (l+r)>>1;
 89     NewNode(x,father,a[mid]);
 90     Build(ch[x][0],l,mid-1,x);
 91     Build(ch[x][1],mid+1,r,x);
 92     push_up(x);
 93 }
 94 
 95 void Init()
 96 {
 97     root = tot1 = tot2 = 0;
 98     ch[root][0] = ch[root][1] = sz[root] = pre[root] = 0;
 99     rev[root] = key[root] = 0;
100     mi[root] = INF;
101     NewNode(root,0,0);
102     NewNode(ch[root][1],root,0);
103     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
104     Build(Key_value,1,n,ch[root][1]);
105     push_up(ch[root][1]);
106     push_up(root);
107 }
108 void Rotate(int x,int kind)
109 {
110     int y = pre[x];
111     push_down(y);
112     push_down(x);
113     ch[y][!kind] = ch[x][kind];
114     pre[ch[x][kind] ] = y;
115     if(pre[y])
116         ch[pre[y] ][ch[pre[y]][1]==y ] = x;
117     pre[x] = pre[y];
118     ch[x][kind] = y;
119     pre[y] = x;
120     push_up(y);
121 }
122 void Splay(int r,int goal)
123 {
124     push_down(r);
125     while(pre[r] != goal)
126     {
127         if(pre[pre[r] ] == goal)
128         {
129             push_down(pre[r]);
130             push_down(r);
131             Rotate(r,ch[pre[r]][0] == r);
132         }
133         else
134         {
135             push_down(pre[pre[r] ]);
136             push_down(pre[r]);
137             push_down(r);
138             int y = pre[r];
139             int kind = ch[pre[y] ][0] == y;
140             if(ch[y][kind] == r)
141             {
142                 Rotate(r,!kind);
143                 Rotate(r,kind);
144             }
145             else
146             {
147                 Rotate(y,kind);
148                 Rotate(r,kind);
149             }
150         }
151         push_up(r);
152         if(goal == 0) root = r;
153     }
154 }
155 
156 int Get_kth(int r,int k)
157 {
158     push_down(r);
159     int t = sz[ch[r][0] ] + 1;
160     if(t == k) return r;
161     if(t > k) return Get_kth(ch[r][0],k);
162     else return Get_kth(ch[r][1],k-t);
163 }
164 
165 void Insert(int pos,int tot)
166 {
167     for(int i=0;i<tot;i++) scanf("%d",&a[i]);
168     Splay(Get_kth(root,pos+1) , 0);
169     Splay(Get_kth(root,pos+2) , root);
170     Build(Key_value,0,tot-1,ch[root][1]);
171     push_up(ch[root][1]);
172     push_up(root);
173 }
174 void erase(int r)
175 {
176     if(!r) return ;
177     s[++tot2] = r;
178     erase(ch[r][0]);
179     erase(ch[r][1]);
180 }
181 void Delete(int pos,int tot)
182 {
183     Splay(Get_kth(root,pos) ,0);
184     Splay(Get_kth(root,pos+tot+1) , root);
185     erase(Key_value);
186     pre[Key_value] = 0;
187     Key_value = 0;
188     push_up(ch[root][1]);
189     push_up(root);
190 }
191 
192 void Reverse(int pos,int tot)
193 {
194     Splay(Get_kth(root,pos) , 0);
195     Splay(Get_kth(root,pos+tot+1), root);
196     Update_rev(Key_value);
197 }
198 
199 void Add(int pos,int tot,int c)
200 {
201     Splay(Get_kth(root,pos) , 0);
202     Splay(Get_kth(root,pos+tot+1) , root);
203     Update_add(Key_value,c);
204     push_up(ch[root][1]);
205     push_up(root);
206 }
207 
208 int Get_min(int pos,int tot)
209 {
210     Splay(Get_kth(root,pos) , 0);
211     Splay(Get_kth(root,pos+tot+1) , root);
212     return mi[Key_value];
213 }
214 
215 void Revolve(int l,int r,int t)
216 {
217     if(!t) return ;
218     int c = r - t;
219     Splay(Get_kth(root,l) , 0);
220     Splay(Get_kth(root,c+2),root);
221     int tmp = Key_value;
222     Key_value = 0;
223     push_up(ch[root][1]);
224     push_up(root);
225     Splay(Get_kth(root,r-c+l) , 0);
226     Splay(Get_kth(root,r-c+l+1) , root);
227     Key_value = tmp;
228     pre[Key_value] = ch[root][1];
229     push_up(ch[root][1]);
230     push_up(root);
231 }
232 
233 int m;
234 int main()
235 {
236     while(~scanf("%d ",&n))
237     {
238         Init();
239         //debug();
240         scanf("%d ",&m);
241         char op[10];
242         for(int i=0;i<m;i++)
243         {
244             scanf(" %s",op);
245             //printf("i:%d op:%s\n",i,op);
246             int x,y,c,t;
247             if(op[0] == 'A')            //add
248             {
249                 scanf("%d%d%d",&x,&y,&c);
250                 Add(x,y-x+1,c);
251             }
252             else if(op[0] == 'I')       //insert
253             {
254                 scanf("%d",&x);
255                 Insert(x,1);
256             }
257             else if(op[0] == 'D')       //delete
258             {
259                 scanf("%d",&x);
260                 Delete(x,1);
261             }
262             else if(op[0] == 'M')       //min
263             {
264                 scanf("%d%d",&x,&y);
265                 printf("%d\n",Get_min(x,y-x+1));
266             }
267             else if(op[0] == 'R' && op[3] == 'E')//reverse
268             {
269                 scanf("%d%d",&x,&y);
270                 Reverse(x,y-x+1);
271             }
272             else                        //revolve
273             {
274                 scanf("%d%d%d",&x,&y,&t);
275                 t = (t%(y-x+1)+(y-x+1))%(y-x+1);
276                 Revolve(x,y,t);
277             }
278             //debug();
279         }
280     }
281 }

 

posted @ 2016-05-18 17:44  Helica  阅读(214)  评论(0编辑  收藏  举报