• 【POJ3580】【splay版】SuperMemo


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