zoukankan      html  css  js  c++  java
  • HDU 3487:Play with Chain(Splay)

    http://acm.hdu.edu.cn/showproblem.php?pid=3487

    题意:有两种操作:1、Flip l r ,把 l 到 r 这段区间 reverse。2、Cut a b c ,把 a 到 b 这段区间切掉,再把这段区间接到切掉后的第 c 个数的后面。

    思路:做完了上一道变态题目,做这道题目如鱼得水。Cut的时候就是把a 到 b 放到keytree的位置,记录一下当前keytree的值,然后切掉,再把切掉后的第 c 个数转到 root 的位置,再把这个记录的值重新连接回去。要注意当全部询问结束了,要把所有的rev标记pushdown。

      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 300100
     13 #define INF 0x3f3f3f3f
     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];
     21     int n, root, cnt, ans[N], tol;
     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     }
     32 
     33     void PushUp(int x)
     34     {
     35         sz[x] = sz[lson] + sz[rson] + 1;
     36     }
     37 
     38     int NewNode(int w, int f, int kind)
     39     {
     40         int x = ++cnt;
     41         ch[x][0] = ch[x][1] = rev[x] = 0;
     42         sz[x] = 1; val[x] = w; fa[x] = f;
     43         ch[f][kind] = cnt;
     44         return x;
     45     }
     46 
     47     void Build(int l, int r, int &x, int f, int kind)
     48     {
     49         if(l > r) return ;
     50         int m = (l + r) >> 1;
     51         x = NewNode(num[m], f, kind);
     52         Build(l, m - 1, ch[x][0], x, 0);
     53         Build(m + 1, r, ch[x][1], x, 1);
     54         PushUp(x);
     55     }
     56 
     57     void Init()
     58     {
     59         root = cnt = tol = 0;
     60         rev[0] = val[0] = fa[0] = sz[0] = ch[0][0] = ch[0][1] = 0;
     61         root = NewNode(0, 0, 0);
     62         ch[root][1] = NewNode(0, root, 1);
     63         sz[root] = 2;
     64         Build(1, n, keytree, ch[root][1], 0);
     65         PushUp(ch[root][1]); PushUp(root);
     66     }
     67 
     68     void Rotate(int x, int kind)
     69     {
     70         int y = fa[x], z = fa[y];
     71         PushDown(y); PushDown(x);
     72         ch[y][!kind] = ch[x][kind];
     73         if(ch[y][!kind]) fa[ch[y][!kind]] = y;
     74         if(z) {
     75             if(y == ch[z][0]) ch[z][0] = x;
     76             else ch[z][1] = x;
     77         }
     78         fa[x] = z; fa[y] = x;
     79         ch[x][kind] = y;
     80         PushUp(y);
     81     }
     82 
     83     void Splay(int x, int goal)
     84     {
     85         while(fa[x] != goal) {
     86             int y = fa[x], z = fa[y];
     87             PushDown(z); PushDown(y); PushDown(x);
     88             int kind1 = x == ch[y][0];
     89             int kind2 = y == ch[z][0];
     90             if(z == goal) {
     91                 Rotate(x, kind1);
     92             } else {
     93                 if(kind1 == kind2) {
     94                     Rotate(y, kind1);
     95                 } else {
     96                     Rotate(x, kind1);
     97                 }
     98                 Rotate(x, kind2);
     99             }
    100         }
    101         PushUp(x);
    102         if(goal == 0) root = x;
    103     }
    104 
    105     void RTO(int k, int goal)
    106     {
    107         int x = root;
    108         PushDown(x);
    109         while(k != sz[lson] + 1) {
    110             if(k <= sz[lson]) x = lson;
    111             else k -= sz[lson] + 1, x = rson;
    112             PushDown(x);
    113         }
    114         Splay(x, goal);
    115     }
    116 
    117     void Cut(int l, int r, int c)
    118     {
    119         RTO(l, 0);
    120 //        Debug();
    121         RTO(r + 2, root);
    122         int tmp = keytree;
    123         keytree = 0;
    124 //        Debug();
    125         RTO(c + 1, 0);
    126 //        Debug();
    127         RTO(c + 2, root);
    128         fa[tmp] = ch[root][1];
    129         keytree = tmp;
    130     }
    131 
    132     void Reverse(int l, int r)
    133     {
    134         RTO(l, 0); RTO(r + 2, root);
    135         rev[keytree] ^= 1;
    136     }
    137 
    138     void Down(int x)
    139     {
    140         PushDown(x);
    141         if(lson) Down(lson);
    142         if(rson) Down(rson);
    143     }
    144 
    145     void Travel(int x)
    146     {
    147         if(lson) Travel(lson);
    148         ans[tol++] = val[x];
    149         if(rson) Travel(rson);
    150     }
    151 
    152     void Debug()
    153     {
    154         Down(root);
    155         Travel(root);
    156         for(int i = 1; i <= n; i++) {
    157             if(i == n) printf("%d
    ", ans[i]);
    158             else printf("%d ", ans[i]);
    159         }
    160     }
    161 }spy;
    162 
    163 int main()
    164 {
    165     int n, m;
    166     while(scanf("%d%d", &n, &m)) {
    167         if(n < 0 || m < 0) break;
    168         spy.n = n;
    169         for(int i = 1; i <= n; i++) spy.num[i] = i;
    170         spy.Init();
    171         while(m--) {
    172             char s[10];
    173             int a, b, c;
    174             scanf("%s", s);
    175             if(s[0] == 'C') {
    176                 scanf("%d%d%d", &a, &b, &c);
    177                 spy.Cut(a, b, c);
    178             } else {
    179                 scanf("%d%d", &a, &b);
    180                 spy.Reverse(a, b);
    181             }
    182         }
    183         spy.Debug();
    184     }
    185     return 0;
    186 }
  • 相关阅读:
    MySQL之视图
    C# 学习笔记(二) 时间格式化字符串
    C# 学习笔记(一) Winform利用Assembly反射动态创建窗体
    puppet 4.4 System Requirements
    Linux下MySql启动时报错
    Linux Iptables
    Nginx Configure时配置
    Wireshark 使用教程
    Linux 下安装oracle数据库
    CaseFile
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6062260.html
Copyright © 2011-2022 走看看