zoukankan      html  css  js  c++  java
  • POJ 3580:SuperMemo(Splay)

    http://poj.org/problem?id=3580

    题意:有6种操作,其中有两种之前没做过,就是Revolve操作和Min操作。Revolve一开始想着一个一个删一个一个插,觉得太暴力了,后来发现可以把要放到前面的一段切开,丢到前面去,就和上一题的Cut是一样的了。还有Min操作,一开始特别ZZ地想着只要找keytree的最左边就好了,然后发现并不是那样的,要维护一个 mi 值,一开始两个节点设成 INF,然后 pushup 的时候先把 val 赋给 mi,然后再和左右儿子对比。WA了好几次,找了下数据。。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <string>
      7 #include <iostream>
      8 #include <stack>
      9 #include <map>
     10 #include <queue>
     11 using namespace std;
     12 #define N 1000100
     13 #define INF 0x7fffffff
     14 #define lson ch[x][0]
     15 #define rson ch[x][1]
     16 #define keytree ch[ch[root][1]][0]
     17 
     18 struct SplayTree
     19 {
     20     int num[N], rev[N], ch[N][2], fa[N], val[N], sz[N], col[N], mi[N];
     21     int n, root, cnt;
     22 
     23     void PushDown(int x)
     24     {
     25         if(rev[x]) {
     26             swap(lson, rson);
     27             if(lson) rev[lson] ^= 1;
     28             if(rson) rev[rson] ^= 1;
     29             rev[x] = 0;
     30         }
     31         if(col[x]) {
     32             if(lson) {
     33                 col[lson] += col[x];
     34                 val[lson] += col[x];
     35                 mi[lson] += col[x];
     36             }
     37             if(rson) {
     38                 col[rson] += col[x];
     39                 val[rson] += col[x];
     40                 mi[rson] += col[x];
     41             }
     42             col[x] = 0;
     43         }
     44     }
     45 
     46     void PushUp(int x)
     47     {
     48         sz[x] = sz[lson] + sz[rson] + 1;
     49         mi[x] = val[x];
     50         if(lson) mi[x] = min(mi[x], mi[lson]);
     51         if(rson) mi[x] = min(mi[x], mi[rson]);
     52     }
     53 
     54     int NewNode(int w, int f, int kind)
     55     {
     56         int x = ++cnt;
     57         ch[x][0] = ch[x][1] = rev[x] = col[x] = 0;
     58         sz[x] = 1; val[x] = w; fa[x] = f;
     59         mi[x] = w;
     60         ch[f][kind] = cnt;
     61         return x;
     62     }
     63 
     64     void Build(int l, int r, int &x, int f, int kind)
     65     {
     66         if(l > r) return ;
     67         int m = (l + r) >> 1;
     68         x = NewNode(num[m], f, kind);
     69         Build(l, m - 1, ch[x][0], x, 0);
     70         Build(m + 1, r, ch[x][1], x, 1);
     71         PushUp(x);
     72     }
     73 
     74     void Init()
     75     {
     76         root = cnt = 0;
     77         rev[0] = val[0] = col[0] = fa[0] = sz[0] = ch[0][0] = ch[0][1] = 0;
     78         mi[0] = INF;
     79         root = NewNode(INF, 0, 0);
     80         ch[root][1] = NewNode(INF, root, 1);
     81         val[ch[root][1]] = INF;
     82         sz[root] = 2;
     83         Build(1, n, keytree, ch[root][1], 0);
     84         PushUp(ch[root][1]); PushUp(root);
     85     }
     86 
     87     void Rotate(int x, int kind)
     88     {
     89         int y = fa[x], z = fa[y];
     90         PushDown(y); PushDown(x);
     91         ch[y][!kind] = ch[x][kind];
     92         if(ch[y][!kind]) fa[ch[y][!kind]] = y;
     93         if(z) {
     94             if(y == ch[z][0]) ch[z][0] = x;
     95             else ch[z][1] = x;
     96         }
     97         fa[x] = z; fa[y] = x;
     98         ch[x][kind] = y;
     99         PushUp(y);
    100     }
    101 
    102     void Splay(int x, int goal)
    103     {
    104 //        printf("%d, %d
    ", x, fa[x]);
    105         PushDown(x);
    106         while(fa[x] != goal) {
    107             int y = fa[x], z = fa[y];
    108             PushDown(z); PushDown(y); PushDown(x);
    109             int kind1 = x == ch[y][0];
    110             int kind2 = y == ch[z][0];
    111             if(z == goal) {
    112                 Rotate(x, kind1);
    113             } else {
    114                 if(kind1 == kind2) {
    115                     Rotate(y, kind1);
    116                 } else {
    117                     Rotate(x, kind1);
    118                 }
    119                 Rotate(x, kind2);
    120             }
    121         }
    122         PushUp(x);
    123         if(goal == 0) root = x;
    124     }
    125 
    126     void RTO(int k, int goal)
    127     {
    128         int x = root;
    129         PushDown(x);
    130         while(k != sz[lson] + 1) {
    131             if(k <= sz[lson]) x = lson;
    132             else k -= sz[lson] + 1, x = rson;
    133             PushDown(x);
    134         }
    135 //        printf("%d, %d, %d
    ", x, val[x], goal);
    136         Splay(x, goal);
    137     }
    138 
    139     void Add(int l, int r, int d)
    140     {
    141         RTO(l, 0); RTO(r + 2, root);
    142         col[keytree] += d;
    143         val[keytree] += d;
    144         mi[keytree] += d;
    145         PushUp(ch[root][1]); PushUp(root);
    146     }
    147 
    148     void Reverse(int l, int r)
    149     {
    150         RTO(l, 0); RTO(r + 2, root);
    151         rev[keytree] ^= 1;
    152         PushUp(ch[root][1]); PushUp(root);
    153     }
    154 
    155     void Cut(int l, int r, int c)
    156     {
    157         RTO(l, 0); RTO(r + 2, root);
    158         PushUp(ch[root][1]); PushUp(root);
    159 //      Debug();
    160 //      puts("---------");
    161         int tmp = keytree;
    162         keytree = 0;
    163         RTO(c, 0); RTO(c + 1, root);
    164         keytree = tmp;
    165         fa[tmp] = ch[root][1];
    166         PushUp(ch[root][1]); PushUp(root);
    167     }
    168 
    169     void Revolve(int l, int r, int t)
    170     {
    171         t = (t % (r - l + 1) + (r - l + 1)) % (r - l + 1);
    172         if(t == 0) return ;
    173         Cut(r - t + 1, r, l);
    174 //        Debug();
    175         PushUp(ch[root][1]); PushUp(root);
    176     }
    177 
    178     void Insert(int index, int w)
    179     {
    180         RTO(index + 1, 0); RTO(index + 2, root);
    181         keytree = NewNode(w, ch[root][1], 0);
    182         PushUp(ch[root][1]); PushUp(root);
    183     }
    184 
    185     void Delete(int index)
    186     {
    187         RTO(index, 0); RTO(index + 2, root);
    188         keytree = 0;
    189         PushUp(ch[root][1]); PushUp(root);
    190     }
    191 
    192     int Query(int l, int r)
    193     {
    194         RTO(l, 0);
    195         RTO(r + 2, root);
    196 //        Debug();
    197         return mi[keytree];
    198     }
    199 
    200     void Travel(int x)
    201     {
    202         if(lson) Travel(lson);
    203         printf("ttt : %d, %d, %d
    ", x, val[x], mi[x]);
    204         if(rson) Travel(rson);
    205     }
    206 
    207     void Debug()
    208     {
    209         Travel(root);
    210     }
    211 }spy;
    212 
    213 int main()
    214 {
    215     int n;
    216     while(~scanf("%d", &n)) {
    217         spy.n = n;
    218         for(int i = 1; i <= n; i++) scanf("%d", &spy.num[i]);
    219         spy.Init();
    220         int m;
    221         scanf("%d", &m);
    222         while(m--) {
    223             char s[10];
    224             int a, b, c;
    225             scanf("%s", s);
    226             if(s[0] == 'A') {
    227                 scanf("%d%d%d", &a, &b, &c);
    228                 spy.Add(a, b, c);
    229             } else if(s[0] == 'M') {
    230                 scanf("%d%d", &a, &b);
    231                 printf("%d
    ", spy.Query(a, b));
    232             } else if(s[0] == 'R' && s[3] == 'E') {
    233                 scanf("%d%d", &a, &b);
    234                 spy.Reverse(a, b);
    235             } else if(s[0] == 'R' && s[3] == 'O') {
    236                 scanf("%d%d%d", &a, &b, &c);
    237                 spy.Revolve(a, b, c);
    238             } else if(s[0] == 'I') {
    239                 scanf("%d%d", &a, &b);
    240                 spy.Insert(a, b);
    241             } else if(s[0] == 'D') {
    242                 scanf("%d", &a);
    243                 spy.Delete(a);
    244             }
    245 //            spy.Debug();
    246         }
    247     }
    248     return 0;
    249 }
    250 
    251 /*
    252 5
    253 1
    254 2
    255 3
    256 4
    257 5
    258 2
    259 REVOLVE 1 5 4
    260 MIN 4 5
    261 
    262 10
    263 1 2 3 4 5 6 7 8 9 10
    264 15
    265 ADD 4 8 3
    266 MIN 5 7
    267 MIN 7 10
    268 REVERSE 2 5
    269 MIN 2 6
    270 MIN 2 3
    271 INSERT 3 4
    272 MIN 3 4
    273 MIN 5 10
    274 DELETE 6
    275 MIN 3 5
    276 MIN 4 4
    277 REVOLVE 3 6 7
    278 MIN 5 8
    279 MIN 7 10
    280 **************************
    281 282 283 284 285 286 287 288 289 290 291 */
  • 相关阅读:
    0045 Spring中使用DataSourceTransactionManager进行事务管理的xml配置
    0044 spring框架的applicationContext.xml的命名空间
    0042 MySQL学习笔记-入门--01
    0041 Java学习笔记-多线程-线程池、ForkJoinPool、ThreadLocal
    0040 Java学习笔记-多线程-线程run()方法中的异常
    0039 Java学习笔记-多线程-线程控制、线程组
    ThinkPHP5.0 实现 app微信支付功能
    Thinkphp5.0分页和跳页
    php header函数导出excel表格
    php之微信公众号发送模板消息
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6063541.html
Copyright © 2011-2022 走看看