EntropyIncreaser

POJ3580 SuperMemo

Dec 4th, 2017
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.02 KB | None | 0 0
  1. #include <cstdio>
  2. #include <climits>
  3.  
  4. #include <algorithm>
  5.  
  6. #define LOG(FMT...) // fprintf(stderr, FMT)
  7.  
  8. using namespace std;
  9.  
  10. typedef long long ll;
  11.  
  12. struct node {
  13.     ll x, d, cnt, lazy;
  14.     bool rev;
  15.     node *ls, *rs;
  16. };
  17.  
  18. typedef ll (*func)(node*&);
  19.  
  20. const int N = 100010, M = N;
  21.  
  22. int n, m;
  23. ll arg;
  24. ll arr[N];
  25. char s[20];
  26. node* root;
  27.  
  28. ll act(int l, int r, func f);
  29. ll get_d(node*& p);
  30. ll add(node*& p);
  31. ll reverse(node*& p);
  32. ll insert(node*& p);
  33. ll remove(node*& p);
  34. int get_cnt(node* p);
  35. void update(node* p);
  36. void push_down(node* p);
  37. void splay(node*& p, int x);
  38. void zig(node*& p);
  39. void zag(node*& p);
  40. void order(node* p);
  41. node* build(int x, int y);
  42.  
  43. int main() {
  44.     int x, y, a;
  45.     scanf("%d", &n);
  46.     for (int i = 1; i <= n; ++i)
  47.         scanf("%lld", &arr[i]);
  48.     root = build(-1, n + 1);
  49.     scanf("%d", &m);
  50.     while (m--) {
  51.         scanf("%s %d", s, &x);
  52.         switch (s[0]) {
  53.         case 'A':
  54.             scanf("%d%lld", &y, &arg);
  55.             act(x, y, add);
  56.             break;
  57.         case 'I':
  58.             act(x, x, insert);
  59.             break;
  60.         case 'D':
  61.             act(x, x, remove);
  62.             break;
  63.         case 'M':
  64.             scanf("%d", &y);
  65.             printf("%lld\n", act(x, y, get_d));
  66.             break;
  67.         default:
  68.             if (s[3] == 'E') {
  69.                 scanf("%d", &y);
  70.                 act(x, y, reverse);
  71.             } else {
  72.                 scanf("%d%d", &y, &a);
  73.                 if (x > y)
  74.                     swap(x, y);
  75.                 a %= y - x + 1;
  76.                 if (a < 0)
  77.                     a += y - x + 1;
  78.                 if (a == 0)
  79.                     break;
  80.                 LOG("ROTATE: %d\n", a);
  81.                 act(x, y, reverse);
  82.                 act(x, x + a - 1, reverse);
  83.                 act(x + a, y, reverse);
  84.             }
  85.         }
  86.     }
  87.     return 0;
  88. }
  89.  
  90. void order(node* p) {
  91.     if (!p)
  92.         return;
  93.     push_down(p);
  94.     order(p->ls);
  95.     printf(" %lld", p->x);
  96.     order(p->rs);
  97. }
  98.  
  99. ll act(int l, int r, func f) {
  100.     l += 2;
  101.     r += 2;
  102.     push_down(root);
  103.     splay(root, l - 1);
  104.     push_down(root->rs);
  105.     splay(root->rs, r - l + 2);
  106.     push_down(root->rs->ls);
  107.     int ret = f(root->rs->ls);
  108.     update(root->rs);
  109.     update(root);
  110.     return ret;
  111. }
  112.  
  113. node* build(int x, int y) {
  114.     static node pool[N + M];
  115.     static int cnt;
  116.     if (x > y)
  117.         return NULL;
  118.     node* p = pool + cnt;
  119.     ++cnt;
  120.     int mid = (x + y) >> 1;
  121.     p->cnt = y - x + 1;
  122.     p->ls = build(x, mid - 1);
  123.     if (mid >= 0)
  124.         p->x = arr[mid];
  125.     p->rs = build(mid + 1, y);
  126.     p->d = min(p->x, min(get_d(p->ls), get_d(p->rs)));
  127.     return p;
  128. }
  129.  
  130. ll add(node*& p) {
  131.     p->lazy += arg;
  132.     return 0;
  133. }
  134.  
  135. ll get_d(node*& p) {
  136.     if (!p)
  137.         return LLONG_MAX;
  138.     return p->d + p->lazy;
  139. }
  140.  
  141. ll reverse(node*& p) {
  142.     p->rev ^= true;
  143.     return 0;
  144. }
  145.  
  146. ll insert(node*& p) {
  147.     scanf("%lld", &arr[0]);
  148.     p->rs = build(0, 0);
  149.     update(p);
  150.     ++n;
  151.     return 0;
  152. }
  153.  
  154. ll remove(node*& p) {
  155.     p = NULL;
  156.     --n;
  157.     return 0;
  158. }
  159.  
  160. inline void push_down(node* p) {
  161.     if (p->ls) {
  162.         p->ls->rev ^= p->rev;
  163.         p->ls->lazy += p->lazy;
  164.     }
  165.     if (p->rs) {
  166.         p->rs->rev ^= p->rev;
  167.         p->rs->lazy += p->lazy;
  168.     }
  169.     if (p->rev)
  170.         swap(p->ls, p->rs);
  171.     p->rev = false;
  172.     p->x += p->lazy;
  173.     p->d += p->lazy;
  174.     p->lazy = 0;
  175. }
  176.  
  177. void update(node* p) {
  178.     p->cnt = 1 + get_cnt(p->ls) + get_cnt(p->rs);
  179.     p->d = min(p->x, min(get_d(p->ls), get_d(p->rs)));
  180. }
  181.  
  182. inline int get_cnt(node* p)
  183. { return p ? p->cnt : 0; }
  184.  
  185. inline void zig(node*& p) {
  186.     push_down(p);
  187.     node* son = p->ls;
  188.     push_down(son);
  189.     p->ls = son->rs;
  190.     son->rs = p;
  191.     update(p);
  192.     p = son;
  193.     update(p);
  194. }
  195.  
  196. inline void zag(node*& p) {
  197.     push_down(p);
  198.     node* son = p->rs;
  199.     push_down(son);
  200.     p->rs = son->ls;
  201.     son->ls = p;
  202.     update(p);
  203.     p = son;
  204.     update(p);
  205. }
  206.  
  207. void splay(node*& p, int x) {
  208.     push_down(p);
  209.     if (x == get_cnt(p->ls) + 1)
  210.         return;
  211.     if (x <= get_cnt(p->ls)) {
  212.         push_down(p->ls);
  213.         if (x == get_cnt(p->ls->ls) + 1) {
  214.             zig(p);
  215.             return;
  216.         }
  217.         if (x <= get_cnt(p->ls->ls)) {
  218.             splay(p->ls->ls, x);
  219.             zig(p);
  220.             zig(p);
  221.             return;
  222.         }
  223.         splay(p->ls->rs, x - 1 - get_cnt(p->ls->ls));
  224.         zag(p->ls);
  225.         zig(p);
  226.         return;
  227.     }
  228.     x -= 1 + get_cnt(p->ls);
  229.     push_down(p->rs);
  230.     if (x == get_cnt(p->rs->ls) + 1) {
  231.         zag(p);
  232.         return;
  233.     }
  234.     if (x <= get_cnt(p->rs->ls)) {
  235.         splay(p->rs->ls, x);
  236.         zig(p->rs);
  237.         zag(p);
  238.         return;
  239.     }
  240.     splay(p->rs->rs, x - 1 - get_cnt(p->rs->ls));
  241.     zag(p);
  242.     zag(p);
  243. }
Advertisement
Add Comment
Please, Sign In to add comment