首页 > 其他 > 详细

【POJ3580】【splay版】SuperMemo

时间:2015-03-12 00:36:16      阅读:221      评论:0      收藏:0      [点我收藏+]

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

【分析】
真实蛋疼了。。
第一次写的时候居然犯了一个傻逼到极点的错误。。。。
翻转部分不会,是看别人的。不过感觉应该还有不同的写法。
代码写得比较丑,主要是尝试了引用。
技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 #include <vector>
  6 #include <utility>
  7 #include <iomanip>
  8 #include <string>
  9 #include <cmath>
 10 #include <queue>
 11 #include <assert.h>
 12 #include <map>
 13 #include <ctime>
 14 #include <cstdlib>
 15 #define LOCAL
 16 const int MAXN = 200000 + 10;
 17 const int INF = 100000000;
 18 const int SIZE = 450;
 19 const int maxnode =  0x7fffffff + 10;
 20 using namespace std;
 21 typedef struct sp_node * Node;
 22 struct SPLAY{
 23        struct Node{
 24               int val, Min;//分别为值,最小值,大小和lazy下标 
 25               int size, lazy;
 26               bool turn;
 27               Node *parent, *ch[2];
 28               
 29               //初始化 
 30               void NEW(int x){
 31                    Min = val = x;
 32                    size = 1;
 33                    lazy = turn = 0;
 34                    parent = ch[0] = ch[1] = NULL;
 35               }
 36               int cmp(){
 37                   if (parent->ch[0] == this) return 0;
 38                   if (parent->ch[1] == this) return 1;
 39               }
 40               //还是不要写在里面了..
 41               /*void pushdown(){
 42                    
 43               } 
 44               void update(){
 45                    size = 1;
 46                    if (x->ch[0] != NULL) size += x->ch[0]->size;
 47                    if (x->ch[1] != NULL) size += x->ch[0]->size;
 48               }     
 49               */    
 50        }mem[MAXN], *root;//mem为静态数组 
 51        int tot;
 52        
 53        int get(Node *&x){return (x == NULL ? 0 : x->size);}
 54        //————————————————————这一部分不能卸载里面 
 55        //更新 
 56        void update(Node *&x){
 57             if (x == NULL) return;
 58             x->size = 1;
 59             x->Min = x->val;
 60             if (x->ch[0] != NULL) {x->Min = min(x->Min, x->ch[0]->Min);x->size += x->ch[0]->size;}
 61             if (x->ch[1] != NULL) {x->Min = min(x->Min, x->ch[1]->Min);x->size += x->ch[1]->size;}
 62        }
 63        void pushdown(Node *&x){//标记下传 
 64             if (x == NULL) return;
 65             if (x->lazy){
 66                int tmp = x->lazy;
 67                x->val += tmp;
 68                if (x->ch[0] != NULL) {x->ch[0]->lazy += tmp;x->ch[0]->Min += tmp;}
 69                if (x->ch[1] != NULL) {x->ch[1]->lazy += tmp;x->ch[1]->Min += tmp;}
 70                x->lazy = 0;
 71             } 
 72             if (x->turn){//翻转
 73                swap(x->ch[0], x->ch[1]);//swap内部用什么实现的呢? 
 74                
 75                if (x->ch[0] != NULL) x->ch[0]->turn ^= 1;
 76                if (x->ch[1] != NULL) x->ch[1]->turn ^= 1; 
 77                x->turn = 0;
 78             }
 79        }
 80        
 81        //———————————————————————————— 
 82        //旋转,1为右旋, 0为左旋
 83        void Rotate(Node *&x, int d){//不用引用也可以 
 84             Node *y = x->parent;
 85             pushdown(y);//注意顺序 
 86             pushdown(x);
 87             pushdown(x->ch[d]);//这个不要忘了
 88             
 89             y->ch[d ^ 1] = x->ch[d];
 90             if (x->ch[d] != NULL) x->ch[d]->parent = y;
 91             x->parent = y->parent;
 92             if (y->parent != NULL){
 93                if (y->parent->ch[0] == y) y->parent->ch[0] = x;
 94                else y->parent->ch[1] = x;
 95             } 
 96             x->ch[d] = y;
 97             y->parent = x;
 98             update(y);
 99             if (y == root) root = x;//如果是引用要小心root被传下去 
100        } 
101        void debug(){
102             Node *p = new Node;
103             root = new Node;
104             root->ch[1] = p;
105             p->parent = root;
106             printf("%d", p->cmp());
107        }
108        //注意我写的这个跟下午那个不一样,下午那个好麻烦 
109        void splay(Node *&x, Node *&y){
110             pushdown(x);
111             while (x != y){
112                   if(x->parent == y){
113                             if (y->ch[0] == x) Rotate(x, 1);
114                             else Rotate(x,0);
115                             break;
116                   }else{
117                             Node *y = x->parent, *z = y->parent;//注意一定要这样弄一下 
118                             if (z->ch[0] == y)
119                             if (y->ch[0] == x) Rotate(y,1),Rotate(x, 1);
120                             else Rotate(x, 0), Rotate(x, 1); 
121                             else if (y->ch[1] == x) Rotate(y, 0), Rotate(x, 0); 
122                             else Rotate(x, 1), Rotate(x, 0); 
123                             if (z == y) break;
124                   }
125                   update(x);
126             }
127             update(x);
128        }
129        //寻找第k大 
130        void find(Node *&t, int k){
131             int tmp;
132             Node *p = root;
133             while (1){
134                   pushdown(p);
135                   tmp = get(p->ch[0]);
136                   if (k == (tmp + 1)) break;
137                   if (k <= tmp) p = p->ch[0];
138                   else {k -= tmp + 1, p = p->ch[1];}
139             }
140             pushdown(p);
141             splay(p, t);
142        }
143        //插入操作 
144        void Insert(int pos, int val){
145             //还是卡出来 
146             find(root, pos + 1);
147             find(root->ch[1], pos + 2);
148             Node *t = &mem[tot++], *x = root->ch[1];
149             pushdown(root);
150             pushdown(x);
151             t->NEW(val);
152             //直接拆开放中间,放在root->ch[1]->ch[0]应该也可以 
153             t->ch[1] = x;
154             x->parent = t;
155             root->ch[1] = t;
156             t->parent = root;
157             splay(x, root);
158        }
159        //区间加 
160        void Add(int l, int r, int x){
161             find(root, l);
162             find(root->ch[1] , r + 2);
163             Node *t = root->ch[1]->ch[0];
164             pushdown(t);
165             update(t);
166             t->Min += x;
167             t->lazy += x;
168             splay(t, root);
169        }
170        //翻转操作 
171        void Reverse(int l, int r){
172             find(root, l);
173             find(root->ch[1], r + 2);
174             root->ch[1]->ch[0]->turn ^= 1;
175             Node *x = root->ch[1]->ch[0];
176             splay(x, root);
177        }
178        //交换操作,这一段我是看别人的.... 
179        void Revolve(int l, int r, int t){
180             Node *p1, *p2;
181             
182             find(root, l);
183             find(root->ch[1], r + 2);
184             find(root->ch[1]->ch[0], r + 1 - t);
185             
186             p1 = root->ch[1]->ch[0];
187             pushdown(p1);
188             p2 = p1->ch[1];
189             p1->ch[1] = NULL;
190             find(root->ch[1]->ch[0], l + 1);
191             p1 = root->ch[1]->ch[0];
192             pushdown(p1);
193             p1->ch[0] = p2;
194             p2->parent = p1;
195             splay(p2, root);
196        }
197        int getMin(int l, int r){
198             find(root, l);
199             find(root->ch[1], r + 2);
200             Node *x = root->ch[1];
201             pushdown(x);
202             x = x->ch[0];
203             pushdown(x);
204             update(x);
205             return x->Min; 
206        }
207        void Erase(int pos){//删除 
208             find(root, pos);
209             find(root->ch[1], pos + 2);
210             pushdown(root->ch[1]);
211             root->ch[1]->ch[0] = NULL;
212             Node *x = root->ch[1];
213             splay(x, root);
214        }
215        void init(){
216             //注意还要加一个正无穷 
217             tot = 0;
218             root = &mem[tot++];
219             root->NEW(INF);
220             root->ch[1] = &mem[tot++];
221             root->ch[1]->NEW(INF);
222        }
223        void print(Node *t){
224             if (t == NULL) return;
225             print(t->ch[0]);
226             printf("%d ", t->val);
227             if (t->parent != NULL) printf("%d\n", t->parent->val);
228             print(t->ch[1]);
229        }
230 }A;
231 
232 int n, m;
233 //注意在这里为了防止掉到0,所以每个位置都要+1 
234 void init(){//初始化 
235     A.init();
236     scanf("%d", &n);
237     for (int i = 0 ; i < n; i++){
238         int x;
239         scanf("%d", &x);
240         A.Insert(i, x);
241         //printf("%d\n", A.root->val);
242     }
243     //A.print(A.root);
244 }
245 void work(){
246      scanf("%d", &m);
247      for (int i = 1; i <= m; i++){//询问,按顺序来。。 
248            char str[20];
249            scanf("%s", str);
250            if (str[0] == A){
251               int l, r, x;
252               scanf("%d%d%d", &l, &r, &x);
253               A.Add(l, r, x);
254            }else if (str[0] == R){
255               int l, r;
256               scanf("%d%d", &l, &r);
257               if (str[3] == E) A.Reverse(l, r);
258               else{
259                    int x, len;
260                    scanf("%d", &x);
261                    len = r - l + 1;
262                    x = (x % len + len) % len;
263                    if (x == 0 || l == r) continue;//我开始居然傻逼的写在前面.... 
264                    A.Revolve(l, r, x);
265               } 
266            }else if (str[0] == I){
267                  int l, x; 
268                  scanf("%d%d", &l, &x);
269                  A.Insert(l, x);
270            }else if (str[0] == D){
271                  int l;
272                  scanf("%d", &l);
273                  A.Erase(l);
274            }else if (str[0] == M){
275                  int l, r;
276                  scanf("%d%d", &l, &r);
277                  printf("%d\n", A.getMin(l, r));
278            }
279      }
280 }
281 void debug(){
282      
283 }
284 
285 int main(){
286     
287     init();
288     work();
289     //debug();
290     //A.debug();
291     return 0;
292 }
View Code

 

【POJ3580】【splay版】SuperMemo

原文:http://www.cnblogs.com/hoskey/p/4331221.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!