HDU 4453 Looploop (伸展树splay tree)

Looploop

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 781    Accepted Submission(s): 220

Problem Description XXX gets a new toy named Looploop. The toy has N elements arranged in a loop, an arrow pointing to one of the elements, and two preset parameters k1 and k2. Every element has a number on it.

The figure above shows a Looploop of 6 elments. Let’s assuming the preset parameter k1 is 3, and k2 is 4.

XXX can do six operations with the toy. 

1: add x 

Starting from the arrow pointed element, add x to the number on the clockwise first k2 elements.

2: reverse

Starting from the arrow pointed element, reverse the first k1 clockwise elements.

3: insert x 

Insert a new element with number x to the right (along clockwise) of the arrow pointed element.

4: delete 

Delete the element the arrow pointed and then move the arrow to the right element.

5: move x 

x can only be 1 or 2. If x = 1 , move the arrow to the left(along the counterclockwise) element, if x = 2 move the arrow to the right element.

6: query

Output the number on the arrow pointed element in one line.

XXX wants to give answers to every query in a serial of operations.  

 

Input There are multiple test cases.

For each test case the first line contains N,M,k1,k2(2≤k1<k2≤N≤10
5, M≤10
5) indicating the initial number of elements, the total number of operations XXX will do and the two preset parameters of the toy. 

Second line contains N integers ai(-10
4≤ai≤10
4) representing the N numbers on the elements in Looploop along clockwise direction. The arrow points to first element in input at the beginning. 

Then m lines follow, each line contains one of the six operations described above.

It is guaranteed that the “x” in the “add”,”insert” and “move” operations is always integer and its absolute value ≤104. The number of elements will never be less than N during the operations. 

The input ends with a line of 0 0 0 0.  

 

Output For each test case, output case number in the first line(formatted as the sample output). Then for each query in the case, output the number on the arrow pointed element in a single line.  

 

Sample Input 5 1 2 4 3 4 5 6 7 query 5 13 2 4 1 2 3 4 5 move 2 query insert 8 reverse query add 2 query move 1 query move 1 query delete query 0 0 0 0  

 

Sample Output Case #1: 3 Case #2: 2 8 10 1 5 1  

 

Source
2012 Asia Hangzhou Regional Contest  

 

 

 

 

用splay tree解决很容易实现。

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013-10-22 16:10:40
  4 ************************************************ */
  5 
  6 #include <stdio.h>
  7 #include <string.h>
  8 #include <iostream>
  9 #include <algorithm>
 10 #include <vector>
 11 #include <queue>
 12 #include <set>
 13 #include <map>
 14 #include <string>
 15 #include <math.h>
 16 #include <stdlib.h>
 17 #include <time.h>
 18 using namespace std;
 19 
 20 #define Key_value ch[ch[root][1]][0]
 21 const int MAXN = 200010;
 22 
 23 int pre[MAXN],ch[MAXN][2],key[MAXN],size[MAXN];
 24 int root,tot1;
 25 int s[MAXN],tot2;
 26 int rev[MAXN],add[MAXN];
 27 int n,q,k1,k2;
 28 int a[MAXN];
 29 int tp;//指针
 30 void NewNode(int &r,int father,int k)
 31 {
 32     if(tot2)r = s[tot2--];
 33     else r = ++tot1;
 34     pre[r] = father;
 35     ch[r][0] = ch[r][1] = 0;
 36     key[r] = k;
 37     add[r] = 0;
 38     rev[r] = 0;
 39     size[r] = 1;
 40 }
 41 void Update_Rev(int r)
 42 {
 43     if(!r)return;
 44     swap(ch[r][0],ch[r][1]);
 45     rev[r] ^= 1;
 46 }
 47 void Update_ADD(int r,int ADD)
 48 {
 49     if(!r)return;
 50     key[r] += ADD;
 51     add[r] += ADD;
 52 }
 53 
 54 void push_up(int r)
 55 {
 56     size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
 57 }
 58 void push_down(int r)
 59 {
 60     if(add[r])
 61     {
 62         Update_ADD(ch[r][0],add[r]);
 63         Update_ADD(ch[r][1],add[r]);
 64         add[r] = 0;
 65     }
 66     if(rev[r])
 67     {
 68         Update_Rev(ch[r][0]);
 69         Update_Rev(ch[r][1]);
 70         rev[r] = 0;
 71     }
 72 }
 73 void Build(int &x,int l,int r,int father)
 74 {
 75     if(l > r)return;
 76     int mid = (l+r)/2;
 77     NewNode(x,father,a[mid]);
 78     Build(ch[x][0],l,mid-1,x);
 79     Build(ch[x][1],mid+1,r,x);
 80     push_up(x);
 81 }
 82 void Init()
 83 {
 84     root = tot1 = tot2 = 0;
 85     ch[root][0] = ch[root][1] = size[root] = pre[root] = 0;
 86     rev[root] = 0;
 87     add[root] = 0;
 88     NewNode(root,0,-1);
 89     NewNode(ch[root][1],root,-1);
 90     for(int i = 0;i < n;i++)
 91         scanf("%d",&a[i]);
 92     Build(Key_value,0,n-1,ch[root][1]);
 93     push_up(ch[root][1]);
 94     push_up(root);
 95 }
 96 //旋转,0为左旋,1为右旋
 97 void Rotate(int x,int kind)
 98 {
 99     int y = pre[x];
100     push_down(y);
101     push_down(x);
102     ch[y][!kind] = ch[x][kind];
103     pre[ch[x][kind]] = y;
104     if(pre[y])
105         ch[pre[y]][ch[pre[y]][1]==y] = x;
106     pre[x] = pre[y];
107     ch[x][kind] = y;
108     pre[y] = x;
109     push_up(y);
110 }
111 void Splay(int r,int goal)
112 {
113     push_down(r);
114     while(pre[r] != goal)
115     {
116         if(pre[pre[r]] == goal)
117         {
118             push_down(pre[r]);
119             push_down(r);
120             Rotate(r,ch[pre[r]][0] == r);
121         }
122         else
123         {
124             push_down(pre[pre[r]]);
125             push_down(pre[r]);
126             push_down(r);
127             int y = pre[r];
128             int kind = ch[pre[y]][0]==y;
129             if(ch[y][kind] == r)
130             {
131                 Rotate(r,!kind);
132                 Rotate(r,kind);
133             }
134             else
135             {
136                 Rotate(y,kind);
137                 Rotate(r,kind);
138             }
139         }
140     }
141     push_up(r);
142     if(goal == 0) root = r;
143 }
144 int Get_kth(int r,int k)
145 {
146     push_down(r);
147     int t = size[ch[r][0]] + 1;
148     if(t == k)return r;
149     if(t > k)return Get_kth(ch[r][0],k);
150     else return Get_kth(ch[r][1],k-t);
151 }
152 void ADD(int x)
153 {
154     //先搬移动
155     Splay(tp,0);
156     int tmp = size[ch[root][0]] + 1;
157     Splay(Get_kth(root,1),0);
158     Splay(Get_kth(root,tmp),root);
159     tmp = Key_value;
160     Key_value = 0;
161     push_up(ch[root][1]);
162     push_up(root);
163     Splay(Get_kth(root,size[root] - 1),0);
164     Key_value = tmp;
165     pre[Key_value] = ch[root][1];
166     push_up(ch[root][1]);
167     push_up(root);
168     Splay(Get_kth(root,1),0);
169     Splay(Get_kth(root,k2+2),root);
170     Update_ADD(Key_value,x);
171     push_up(ch[root][1]);
172     push_up(root);
173     tp = Get_kth(root,2);
174 }
175 void REVERSE()
176 {
177     Splay(tp,0);
178     int tmp = size[ch[root][0]] + 1;
179     Splay(Get_kth(root,1),0);
180     Splay(Get_kth(root,tmp),root);
181     tmp = Key_value;
182     Key_value = 0;
183     push_up(ch[root][1]);
184     push_up(root);
185     Splay(Get_kth(root,size[root] - 1),0);
186     Key_value = tmp;
187     pre[Key_value] = ch[root][1];
188     push_up(ch[root][1]);
189     push_up(root);
190     Splay(Get_kth(root,1),0);
191     Splay(Get_kth(root,k1+2),root);
192     Update_Rev(Key_value);
193     push_up(ch[root][1]);
194     push_up(root);
195     tp = Get_kth(root,2);
196 }
197 void INSERT(int x)
198 {
199     Splay(tp,0);
200     //printf("%d %d\n",tp,size[ch[root][0]]+2);
201     int tt = Get_kth(root,size[ch[root][0]]+2);
202     //printf("%d %d %d\n",Get_kth(root,size[ch[root][0]]+2),tt,key[tt]);
203     Splay(Get_kth(root,size[ch[root][0]]+2),root);
204     NewNode(Key_value,ch[root][1],x);
205     push_up(ch[root][1]);
206     push_up(root);
207 }
208 void DELETE()
209 {
210     Splay(tp,0);
211     int tmp = size[ch[root][0]] + 1;
212     Splay(Get_kth(root,tmp-1),0);
213     Splay(Get_kth(root,tmp+1),root);
214     s[++tot2] = Key_value;
215     Key_value = 0;
216     push_up(ch[root][1]);
217     push_up(root);
218     if(tmp == size[root])tp = Get_kth(root,2);
219     else tp = Get_kth(root,tmp);
220 }
221 int MOVE(int x)
222 {
223     if(x == 1)
224     {
225         Splay(tp,0);
226         int tmp = size[ch[root][0]] + 1;
227         tmp--;
228         if(tmp == 1)tmp = size[root] - 1;
229         tp = Get_kth(root,tmp);
230     }
231     else
232     {
233         Splay(tp,0);
234         int tmp = size[ch[root][0]] + 1;
235         tmp++;
236         if(tmp == size[root])tmp = 2;
237         tp = Get_kth(root,tmp);
238         //cout<<tp<<endl;
239     }
240 }
241 int query()
242 {
243     Splay(tp,0);
244     return key[root];
245 }
246 char op[100];
247 int x;
248 int main()
249 {
250     //freopen("in.txt","r",stdin);
251     //freopen("out.txt","w",stdout);
252     int iCase = 0;
253     while(scanf("%d%d%d%d",&n,&q,&k1,&k2) == 4)
254     {
255         if(n == 0 && q == 0 && k1 == 0 && k2 == 0)break;
256         iCase ++;
257         printf("Case #%d:\n",iCase);
258         Init();
259         tp = Get_kth(root,2);
260         while(q--)
261         {
262             scanf("%s",op);
263             if(op[0] == 'a')
264             {
265                 scanf("%d",&x);
266                 ADD(x);
267             }
268             else if(op[0] == 'r')
269                 REVERSE();
270             else if(op[0] == 'i')
271             {
272                 scanf("%d",&x);
273                 INSERT(x);
274             }
275             else if(op[0] == 'd')
276                 DELETE();
277             else if(op[0] == 'm')
278             {
279                 scanf("%d",&x);
280                 MOVE(x);
281             }
282             else printf("%d\n",query());
283         }
284 
285     }
286     return 0;
287 }

 

 

 

 

 

 

 

 

 

    原文作者:算法小白
    原文地址: https://www.cnblogs.com/kuangbin/p/3383423.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞