POJ 3580 SuperMemo (splay tree)

SuperMemo

Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 6841 Accepted: 2268
Case Time Limit: 2000MS

Description

Your friend, Jackson is invited to a TV show called SuperMemo in which the participant is told to play a memorizing game. At first, the host tells the participant a sequence of numbers, {A1A2, … An}. Then the host performs a series of operations and queries on the sequence which consists:

  1. ADD x y D: Add D to each number in sub-sequence {Ax … Ay}. For example, performing “ADD 2 4 1″ on {1, 2, 3, 4, 5} results in {1, 3, 4, 5, 5}
  2. REVERSE x y: reverse the sub-sequence {Ax … Ay}. For example, performing “REVERSE 2 4″ on {1, 2, 3, 4, 5} results in {1, 4, 3, 2, 5}
  3. REVOLVE x y T: rotate sub-sequence {Ax … AyT times. For example, performing “REVOLVE 2 4 2″ on {1, 2, 3, 4, 5} results in {1, 3, 4, 2, 5}
  4. INSERT x P: insert P after Ax. For example, performing “INSERT 2 4″ on {1, 2, 3, 4, 5} results in {1, 2, 4, 3, 4, 5}
  5. DELETE x: delete Ax. For example, performing “DELETE 2″ on {1, 2, 3, 4, 5} results in {1, 3, 4, 5}
  6. MIN x y: query the participant what is the minimum number in sub-sequence {Ax … Ay}. For example, the correct answer to “MIN 2 4″ on {1, 2, 3, 4, 5} is 2

To make the show more interesting, the participant is granted a chance to turn to someone else that means when Jackson feels difficult in answering a query he may call you for help. You task is to watch the TV show and write a program giving the correct answer to each query in order to assist Jackson whenever he calls.

Input

The first line contains (≤ 100000).

The following n lines describe the sequence.

Then follows M (≤ 100000), the numbers of operations and queries.

The following M lines describe the operations and queries.

Output

For each “MIN” query, output the correct answer.

Sample Input

5
1 
2 
3 
4 
5
2
ADD 2 4 1
MIN 4 5

Sample Output

5

Source

POJ Founder Monthly Contest – 2008.04.13, Yao Jinyu

 

 

 

 

 

  1 /* ***********************************************
  2 Author        :kuangbin
  3 Created Time  :2013/8/28 19:39:45
  4 File Name     :F:\2013ACM练习\专题学习\splay_tree_2\POJ3580.cpp
  5 ************************************************ */
  6 
  7 #include <stdio.h>
  8 #include <string.h>
  9 #include <iostream>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 #include <set>
 14 #include <map>
 15 #include <string>
 16 #include <math.h>
 17 #include <stdlib.h>
 18 #include <time.h>
 19 using namespace std;
 20 /*
 21  * 给定一个数列:a1,a2,.... an
 22  * 进行以下6种操作:
 23  * ADD x y D : 给第x个数到第y个数加D
 24  * REVERSE x y : 反转[x,y]
 25  * REVOVLE x y T : 对[x,y]区间的数循环右移T次
 26  *     (先把T对长度取模,然后相当于把[y-T+1,y]放到[x,y-T] 的前面)
 27  * INSERT x P  : 在第x个数后面插入P
 28  * DELETE x : 删除第x个数
 29  * MIN x y  : 查询[x,y]之间的最小的数
 30  */
 31 #define Key_value ch[ch[root][1]][0]
 32 const int MAXN = 200010;
 33 const int INF = 0x3f3f3f3f;
 34 int pre[MAXN],ch[MAXN][2],root,tot1,size[MAXN];
 35 int key[MAXN],rev[MAXN],m[MAXN],add[MAXN];
 36 int s[MAXN],tot2;
 37 int a[MAXN];
 38 int n;
 39 void NewNode(int &r,int father,int k)
 40 {
 41     if(tot2) r = s[tot2--];
 42     else r = ++tot1;
 43     pre[r] = father;
 44     ch[r][0] = ch[r][1] = 0;
 45     key[r] = k;
 46     m[r] = k;
 47     rev[r] = add[r] = 0;
 48     size[r] = 1;
 49 }
 50 void Update_Rev(int r)
 51 {
 52     if(!r)return;
 53     swap(ch[r][0],ch[r][1]);
 54     rev[r] ^= 1;
 55 }
 56 void Update_Add(int r,int D)
 57 {
 58     if(!r)return;
 59     m[r] += D;
 60     key[r] += D;
 61     add[r] += D;
 62 }
 63 void push_up(int r)
 64 {
 65     size[r] = size[ch[r][0]] + size[ch[r][1]] + 1;
 66     m[r] = min(key[r],min(m[ch[r][0]],m[ch[r][1]]));
 67 }
 68 void push_down(int r)
 69 {
 70     if(rev[r])
 71     {
 72         Update_Rev(ch[r][0]);
 73         Update_Rev(ch[r][1]);
 74         rev[r] = 0;
 75     }
 76     if(add[r])
 77     {
 78         Update_Add(ch[r][0],add[r]);
 79         Update_Add(ch[r][1],add[r]);
 80         add[r] = 0;
 81     }
 82 }
 83 void Build(int &x,int l,int r,int father)
 84 {
 85     if(l > r)return;
 86     int mid = (l+ r)/2;
 87     NewNode(x,father,a[mid]);
 88     Build(ch[x][0],l,mid-1,x);
 89     Build(ch[x][1],mid+1,r,x);
 90     push_up(x);
 91 }
 92 void Init()
 93 {
 94     root = tot1 = tot2 = 0;
 95     ch[root][0] = ch[root][1] = pre[root] = 0;
 96     rev[root] = add[root] = 0;
 97     m[root] = INF;
 98     size[root] = 0;
 99     NewNode(root,0,-1);
100     NewNode(ch[root][1],root,-1);
101     for(int i = 0;i < n;i++)
102         scanf("%d",&a[i]);
103     Build(Key_value,0,n-1,ch[root][1]);
104     push_up(ch[root][1]);
105     push_up(root);
106 }
107 void Rotate(int x,int kind)
108 {
109     int y = pre[x];
110     push_down(y);
111     push_down(x);
112     ch[y][!kind] = ch[x][kind];
113     pre[ch[x][kind]] = y;
114     if(pre[y])
115         ch[pre[y]][ch[pre[y]][1]==y] = x;
116     pre[x] = pre[y];
117     ch[x][kind] = y;
118     pre[y] = x;
119     push_up(y);
120 }
121 void Splay(int r,int goal)
122 {
123     push_down(r);
124     while(pre[r] != goal)
125     {
126         if(pre[pre[r]] == goal)
127         {
128             push_down(pre[r]);
129             push_down(r);
130             Rotate(r,ch[pre[r]][0]==r);
131         }
132         else
133         {
134             push_down(pre[pre[r]]);
135             push_down(pre[r]);
136             push_down(r);
137             int y = pre[r];
138             int kind = ch[pre[y]][0]==y;
139             if(ch[y][kind] == r)
140             {
141                 Rotate(r,!kind);
142                 Rotate(r,kind);
143             }
144             else
145             {
146                 Rotate(y,kind);
147                 Rotate(r,kind);
148             }
149         }
150     }
151     push_up(r);
152     if(goal == 0) root = r;
153 }
154 
155 int Get_kth(int r,int k)
156 {
157     push_down(r);
158     int t = size[ch[r][0]] + 1;
159     if(t == k) return r;
160     if(t > k) return Get_kth(ch[r][0],k);
161     else return Get_kth(ch[r][1],k-t);
162 }
163 
164 void ADD(int x,int y,int D)
165 {
166     Splay(Get_kth(root,x),0);
167     Splay(Get_kth(root,y+2),root);
168     Update_Add(Key_value,D);
169     push_up(ch[root][1]);
170     push_up(root);
171 }
172 void Reverse(int x,int y)
173 {
174     Splay(Get_kth(root,x),0);
175     Splay(Get_kth(root,y+2),root);
176     Update_Rev(Key_value);
177     push_up(ch[root][1]);
178     push_up(root);
179 }
180 void REVOLVE(int x,int y,int T)
181 {
182     int len = y - x + 1;
183     T = ( T%len + len )%len;
184     Splay(Get_kth(root,y-T+1),0);
185     Splay(Get_kth(root,y+2),root);
186     int tmp = Key_value;
187     Key_value = 0;
188     push_up(ch[root][0]);
189     push_up(root);
190     Splay(Get_kth(root,x),0);
191     Splay(Get_kth(root,x+1),root);
192     Key_value = tmp;
193     pre[tmp] = ch[root][1];
194     push_up(ch[root][1]);
195     push_up(root);
196 }
197 void INSERT(int x,int P)
198 {
199     Splay(Get_kth(root,x+1),0);
200     Splay(Get_kth(root,x+2),root);
201     NewNode(Key_value,ch[root][1],P);
202     push_up(ch[root][1]);
203     push_up(root);
204 }
205 void erase(int r)
206 {
207     if(!r)return;
208     s[++tot2] = r;
209     erase(ch[r][0]);
210     erase(ch[r][1]);
211 }
212 void DELETE(int x)
213 {
214     Splay(Get_kth(root,x),0);
215     Splay(Get_kth(root,x+2),root);
216     erase(Key_value);
217     pre[Key_value] = 0;
218     Key_value = 0;
219     push_up(ch[root][1]);
220     push_up(root);
221 }
222 int MIN(int x,int y)
223 {
224     Splay(Get_kth(root,x),0);
225     Splay(Get_kth(root,y+2),root);
226     return m[Key_value];
227 }
228 int main()
229 {
230     //freopen("in.txt","r",stdin);
231     //freopen("out.txt","w",stdout);
232     while(scanf("%d",&n) == 1)
233     {
234         Init();
235         int x,y,z;
236         char op[20];
237         int q;
238         scanf("%d",&q);
239         while(q--)
240         {
241             scanf("%s",op);
242             if(strcmp(op,"ADD") == 0)
243             {
244                 scanf("%d%d%d",&x,&y,&z);
245                 ADD(x,y,z);
246             }
247             else if(strcmp(op,"REVERSE") == 0)
248             {
249                 scanf("%d%d",&x,&y);
250                 Reverse(x,y);
251             }
252             else if(strcmp(op,"REVOLVE") == 0)
253             {
254                 scanf("%d%d%d",&x,&y,&z);
255                 REVOLVE(x,y,z);
256             }
257             else if(strcmp(op,"INSERT") == 0)
258             {
259                 scanf("%d%d",&x,&y);
260                 INSERT(x,y);
261             }
262             else if(strcmp(op,"DELETE") == 0)
263             {
264                 scanf("%d",&x);
265                 DELETE(x);
266             }
267             else if(strcmp(op,"MIN") == 0)
268             {
269                 scanf("%d%d",&x,&y);
270                 printf("%d\n",MIN(x,y));
271             }
272         }
273     }
274     return 0;
275 }

 

 

 

 

 

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