zoukankan      html  css  js  c++  java
  • 【POJ】3580 SuperMemo

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define oo 0x7FFFFFFF
      5 #define MAXN 200010
      6 using namespace std;
      7 struct SplayTree {
      8     int size, root, top;
      9     int st[MAXN], a[MAXN];
     10     int next[MAXN][2], pre[MAXN], key[MAXN], num[MAXN];
     11     int add[MAXN], mini[MAXN];
     12     bool flip[MAXN];
     13     inline void PushUp(int x) {
     14         num[x] = num[next[x][0]] + num[next[x][1]] + 1;
     15         mini[x] = min(mini[next[x][0]], mini[next[x][1]]);
     16         mini[x] = min(mini[x], key[x]);
     17     }
     18     inline void PushDown(int x) {
     19         int L, R;
     20         L = next[x][0];
     21         R = next[x][1];
     22         if (add[x]) {
     23             if (L) {
     24                 add[L] += add[x];
     25                 key[L] += add[x];
     26                 mini[L] += add[x];
     27             }
     28             if (R) {
     29                 add[R] += add[x];
     30                 key[R] += add[x];
     31                 mini[R] += add[x];
     32             }
     33             add[x] = 0;
     34         }
     35         if (flip[x]) {
     36             flip[L] ^= true;
     37             flip[R] ^= true;
     38             swap(next[x][0], next[x][1]);
     39             flip[x] = false;
     40         }
     41     }
     42     void NewNode(int &x, int father, int val) {
     43         if (top != -1)
     44             x = st[top--];
     45         else
     46             x = ++size;
     47         next[x][0] = next[x][1] = add[x] = 0;
     48         pre[x] = father;
     49         key[x] = mini[x] = val;
     50         num[x] = 1;
     51         flip[x] = false;
     52     }
     53     void Build(int &x, int L, int R, int father) {
     54         if (L <= R) {
     55             int mid = (L + R) >> 1;
     56             NewNode(x, father, a[mid]);
     57             Build(next[x][0], L, mid - 1, x);
     58             Build(next[x][1], mid + 1, R, x);
     59             PushUp(x);
     60         }
     61     }
     62     void Init(int n) {
     63         root = size = 0;
     64         top = -1;
     65         flip[0] = false;
     66         next[0][0] = next[0][1] = pre[0] = num[0] = add[0] = 0;
     67         key[0] = mini[0] = oo;
     68         NewNode(root, 0, oo);
     69         NewNode(next[root][1], root, oo);
     70         Build(next[next[root][1]][0], 1, n, next[root][1]);
     71         PushUp(next[root][1]);
     72         PushUp(root);
     73     }
     74     void Rotate(int x, int kind) {
     75         int y, z;
     76         y = pre[x];
     77         z = pre[y];
     78         PushDown(y);
     79         next[y][!kind] = next[x][kind];
     80         pre[next[x][kind]] = y;
     81         next[z][next[z][1] == y] = x;
     82         pre[x] = z;
     83         next[x][kind] = y;
     84         pre[y] = x;
     85         PushUp(y);
     86     }
     87     void Splay(int x, int goal) {
     88         if (x != goal) {
     89             PushDown(x);
     90             while (pre[x] != goal) {
     91                 if (next[pre[x]][0] == x)
     92                     Rotate(x, 1);
     93                 else
     94                     Rotate(x, 0);
     95             }
     96             PushUp(x);
     97             if (!goal)
     98                 root = x;
     99         }
    100     }
    101     int Select(int k) {
    102         int x;
    103         PushDown(root);
    104         for (x = root; num[next[x][0]] + 1 != k;) {
    105             if (num[next[x][0]] + 1 > k)
    106                 x = next[x][0];
    107             else {
    108                 k -= num[next[x][0]] + 1;
    109                 x = next[x][1];
    110             }
    111             PushDown(x);
    112         }
    113         return x;
    114     }
    115     void Add(int x, int y, int val) {
    116         int t;
    117         x = Select(x - 1);
    118         y = Select(y + 1);
    119         Splay(x, 0);
    120         Splay(y, x);
    121         t = next[y][0];
    122         add[t] += val;
    123         key[t] += val;
    124         mini[t] += val;
    125         PushUp(y);
    126         PushUp(x);
    127     }
    128     void Flip(int x, int y) {
    129         x = Select(x - 1);
    130         y = Select(y + 1);
    131         Splay(x, 0);
    132         Splay(y, x);
    133         flip[next[y][0]] ^= true;
    134     }
    135     void Revolve(int x, int y, int t) {
    136         int cnt = y - x + 1;
    137         t %= cnt;
    138         if (t < 0)
    139             t += cnt;
    140         if (t) {
    141             Flip(x, y - t);
    142             Flip(y - t + 1, y);
    143             Flip(x, y);
    144         }
    145     }
    146     void Insert(int x, int val) {
    147         int a, b;
    148         a = Select(x);
    149         b = Select(x + 1);
    150         Splay(a, 0);
    151         Splay(b, a);
    152         NewNode(next[b][0], b, val);
    153         PushUp(b);
    154         PushUp(a);
    155     }
    156     void Delete(int x) {
    157         int a, b;
    158         a = Select(x - 1);
    159         b = Select(x + 1);
    160         Splay(a, 0);
    161         Splay(b, a);
    162         st[++top] = next[b][0];
    163         next[b][0] = 0;
    164         PushUp(b);
    165         PushUp(a);
    166     }
    167     int MIN(int x, int y) {
    168         x = Select(x - 1);
    169         y = Select(y + 1);
    170         Splay(x, 0);
    171         Splay(y, x);
    172         return mini[next[y][0]];
    173     }
    174 } spt;
    175 int main() {
    176     char cmd[18];
    177     int n, q, i;
    178     int x, y, val;
    179     while (~scanf("%d", &n)) {
    180         for (i = 1; i <= n; i++)
    181             scanf("%d", &spt.a[i]);
    182         spt.Init(n);
    183         scanf("%d", &q);
    184         while (q--) {
    185             scanf(" %s", cmd);
    186             if (strcmp(cmd, "ADD") == 0) {
    187                 scanf("%d%d%d", &x, &y, &val);
    188                 spt.Add(x + 1, y + 1, val);
    189             } else if (strcmp(cmd, "REVERSE") == 0) {
    190                 scanf("%d%d", &x, &y);
    191                 spt.Flip(x + 1, y + 1);
    192             } else if (strcmp(cmd, "REVOLVE") == 0) {
    193                 scanf("%d%d%d", &x, &y, &val);
    194                 spt.Revolve(x + 1, y + 1, val);
    195             } else if (strcmp(cmd, "INSERT") == 0) {
    196                 scanf("%d%d", &x, &val);
    197                 spt.Insert(x + 1, val);
    198             } else if (strcmp(cmd, "DELETE") == 0) {
    199                 scanf("%d", &x);
    200                 spt.Delete(x + 1);
    201             } else {
    202                 scanf("%d%d", &x, &y);
    203                 printf("%d\n", spt.MIN(x + 1, y + 1));
    204             }
    205         }
    206     }
    207     return 0;
    208 }
  • 相关阅读:
    Python学习笔记模式匹配与正则表达式之使用和不使用正则表达式
    关于Jqury的一些杂碎
    客户端验证模型
    导航(摘)
    解决了DIV+CSS一个问题
    购买了新书《Bootstrap用户手册—设计响应式网站》及简介Bootstrap是什么
    博客园的博客页面开通了,今天!
    利用Cmake 将最新版本OBS编译成windows版本。
    C语言无法使用引用,一定要使用怎么办? ------指针的指针做参数
    linux core文件的打开和分析
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2641081.html
Copyright © 2011-2022 走看看