EntropyIncreaser

NOIP2017D2T3 phalanx

Nov 23rd, 2017
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.44 KB | None | 0 0
  1. #include <cstdio>
  2. #include <ctime>
  3.  
  4. #include <algorithm>
  5. #include <utility>
  6.  
  7. #define GET_CH(P, F) ((F) ? (P)->rs : (P)->ls)
  8. #define LOG(FMT...) fprintf(stderr, FMT)
  9.  
  10. using namespace std;
  11.  
  12. typedef long long ll;
  13.  
  14. struct data {
  15.     int step, sz;
  16.     ll start;
  17.    
  18.     data() {}
  19.    
  20.     data(int step, int sz, ll start) : step(step), sz(sz), start(start) {}
  21.    
  22.     data(ll x) : step(0), sz(1), start(x) {}
  23. };
  24.  
  25. struct node {
  26.     int cnt, rnd;
  27.     data x;
  28.     node *ls, *rs;
  29. };
  30.  
  31. struct que {
  32.     node* t;
  33.    
  34.     void insert(ll x);
  35.     ll remove(int x);
  36. };
  37.  
  38. const int N = 300010;
  39.  
  40. node *res1, *res2;
  41. int resy;
  42. que q1[N], q2;
  43.  
  44. int fast_rand();
  45. node* create(const data& x);
  46. int get_cnt(node* p);
  47. void ninsert(node*& p, node* q, int x);
  48. void rotate(node*& p, bool f);
  49. void update(node* p);
  50. pair<data, int> nremove(node*& p, int x);
  51. void debug_order(node* p);
  52.  
  53. int main() {
  54.     int n, m, q, x, y;
  55.     ll id1, id2;
  56.     scanf("%d%d%d", &n, &m, &q);
  57.     for (int i = 1; i <= n; ++i)
  58.         q1[i].t = create(data(1, m - 1, (ll)(i - 1) * m));
  59.     q2.t = create(data(m, n, 0));
  60.     while (q--) {
  61.         scanf("%d%d", &x, &y);
  62.         if (y == m) {
  63.             id2 = q2.remove(x);
  64.             printf("%lld\n", id2);
  65.             q2.insert(id2);
  66.         } else {
  67.             id1 = q1[x].remove(y);
  68.             printf("%lld\n", id1);
  69.             id2 = q2.remove(x);
  70.             q1[x].insert(id2);
  71.             q2.insert(id1);
  72.         }
  73.     }
  74.     return 0;
  75. }
  76.  
  77. inline int fast_rand() {
  78.     static int x = time(NULL) << 4, y = time(NULL) >> 2, z = time(NULL);
  79.     int t;
  80.     x ^= x << 16;
  81.     x ^= x >> 5;
  82.     x ^= x << 1;
  83.     t = x;
  84.     x = y;
  85.     y = z;
  86.     z = t ^ x ^ y;
  87.     return z;
  88. }
  89.  
  90. inline node* create(const data& x) {
  91.     static node pool[N << 3];
  92.     static node* p = pool;
  93.     ++p;
  94.     p->rnd = fast_rand();
  95.     p->x = x;
  96.     p->cnt = x.sz;
  97.     return p;
  98. }
  99.  
  100. inline void rotate(node*& p, bool f) {
  101.     node *son = GET_CH(p, f), *pson = GET_CH(son, !f);
  102.     GET_CH(p, f) = pson;
  103.     GET_CH(son, !f) = p;
  104.     update(p);
  105.     p = son;
  106.     update(p);
  107. }
  108.  
  109. inline int get_cnt(node* p)
  110. { return p ? p->cnt : 0; }
  111.  
  112. inline void update(node* p)
  113. { p->cnt = get_cnt(p->ls) + get_cnt(p->rs) + p->x.sz; }
  114.  
  115. void que::insert(ll x)
  116. { ninsert(t, create(data(x)), get_cnt(t) + 1); }
  117.  
  118. ll que::remove(int x) {
  119.     pair<data, int> p = nremove(t, x);
  120.     data d = p.first;
  121.     int y = p.second;
  122.     if (res2)
  123.         ninsert(t, res2, resy + 1);
  124.     if (res1)
  125.         ninsert(t, res1, resy + 1);
  126.     ll cur = (ll)(x - y) * d.step + d.start;
  127.     if (x - y < d.sz)
  128.         ninsert(t, create(data(d.step, d.sz - x + y, cur)), y + 1);
  129.     if (x - y > 1)
  130.         ninsert(t, create(data(d.step, x - y - 1, d.start)), y + 1);
  131.     return cur;
  132. }
  133.  
  134. pair<data, int> nremove(node*& p, int x) {
  135.     pair<data, int> ret;
  136.     if (x <= get_cnt(p->ls)) {
  137.         ret = nremove(p->ls, x);
  138.         update(p);
  139.         return ret;
  140.     }
  141.     if (get_cnt(p->ls) + p->x.sz >= x) {
  142.         ret = make_pair(p->x, get_cnt(p->ls));
  143.         res1 = p->ls;
  144.         res2 = p->rs;
  145.         p = NULL;
  146.         resy = 0;
  147.         return ret;
  148.     }
  149.     ret = nremove(p->rs, x - get_cnt(p->ls) - p->x.sz);
  150.     resy += get_cnt(p->ls) + p->x.sz;
  151.     ret.second += get_cnt(p->ls) + p->x.sz;
  152.     update(p);
  153.     return ret;
  154. }
  155.  
  156. void ninsert(node*& p, node* q, int x) {
  157.     if (!p) {
  158.         p = q;
  159.         return;
  160.     }
  161.     if (x <= get_cnt(p->ls) + p->x.sz) {
  162.         ninsert(p->ls, q, x);
  163.         update(p);
  164.         if (p->rnd < p->ls->rnd)
  165.             rotate(p, 0);
  166.         return;
  167.     }
  168.     ninsert(p->rs, q, x - get_cnt(p->ls) - p->x.sz);
  169.     update(p);
  170.     if (p->rnd < p->rs->rnd)
  171.         rotate(p, 1);
  172.     return;
  173. }
  174.  
  175. void debug_order(node* p) {
  176.     if (!p)
  177.         return;
  178.     debug_order(p->ls);
  179.     LOG("(%lld %d %d) ", p->x.start, p->x.step, p->x.sz);
  180.     debug_order(p->rs);
  181. }
Advertisement
Add Comment
Please, Sign In to add comment