EntropyIncreaser

2BTree

Nov 27th, 2017
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.53 KB | None | 0 0
  1. #include <climits>
  2. #include <cstdio>
  3. #include <ctime>
  4.  
  5. #include <algorithm>
  6.  
  7. #define LOG(FMT...) // fprintf(stderr, FMT)
  8.  
  9. using namespace std;
  10.  
  11. struct tre {
  12.     int x, cnt, sz, rnd;
  13.     tre *ls, *rs;
  14. };
  15.  
  16. struct seg {
  17.     int l, r;
  18.     tre* root;
  19.     seg *ls, *rs;
  20. };
  21.  
  22. const int N = 50010;
  23.  
  24. int n, m;
  25. tre *res1, *res2;
  26. seg* root;
  27. int a[N];
  28.  
  29. int fast_rand();
  30. seg* construct(int l, int r);
  31. tre* create(int x);
  32. int get_cnt(tre* p);
  33. void update(tre* p);
  34. void insert(tre*& p, int x);
  35. void insert(tre*& p, tre* q);
  36. void remove(tre*& p, int x);
  37. void zig(tre*& p);
  38. void zag(tre*& p);
  39. void change(seg* p, int k, int x);
  40. bool remove_x(tre*& p, int x);
  41. int prev(tre* p, int x);
  42. int post(tre* p, int x);
  43. int get_rank(tre* p, int x);
  44. int get_rank(seg* p, int l, int r, int x);
  45. int get_x(int l, int r, int x);
  46. int prev(seg* p, int l, int r, int x);
  47. int post(seg* p, int l, int r, int x);
  48. void out(int x);
  49.  
  50. int main() {
  51. //  freopen("test.in", "r", stdin);
  52. //  freopen("test.out", "w", stdout);
  53.     int l, r, k, x, op;
  54.     scanf("%d%d", &n, &m);
  55.     for (int i = 1; i <= n; ++i)
  56.         scanf("%d", &a[i]);
  57.     root = construct(1, n);
  58.     while (m--) {
  59.         scanf("%d", &op);
  60.         switch (op) {
  61.         case 1:
  62.             scanf("%d%d%d", &l, &r, &x);
  63.             out(get_rank(root, l, r, x) + 1);
  64.             break;
  65.         case 2:
  66.             scanf("%d%d%d", &l, &r, &k);
  67.             out(get_x(l, r, k - 1));
  68.             break;
  69.         case 3:
  70.             scanf("%d%d", &k, &x);
  71.             change(root, k, x);
  72.             a[k] = x;
  73.             break;
  74.         case 4:
  75.             scanf("%d%d%d", &l, &r, &x);
  76.             out(prev(root, l, r, x));
  77.             break;
  78.         case 5:
  79.             scanf("%d%d%d", &l, &r, &x);
  80.             out(post(root, l, r, x));
  81.             break;
  82.         }
  83.     }
  84.     return 0;
  85. }
  86.  
  87. inline void remove(tre*& p, int x) {
  88.     if (remove_x(p, x)) {
  89.         if (res1)
  90.             insert(p, res1);
  91.         if (res2)
  92.             insert(p, res2);
  93.     }
  94. }
  95.  
  96. inline void out(int x) {
  97.     printf("%d\n", x);
  98. }
  99.  
  100. int get_rank(seg* p, int l, int r, int x) {
  101.     if (p->l == l && p->r == r)
  102.         return get_rank(p->root, x);
  103.     if (r <= p->ls->r)
  104.         return get_rank(p->ls, l, r, x);
  105.     if (l >= p->rs->l)
  106.         return get_rank(p->rs, l, r, x);
  107.     return get_rank(p->ls, l, p->ls->r, x) +
  108.            get_rank(p->rs, p->rs->l, r, x);
  109. }
  110.  
  111. inline int get_rank(tre* p, int x) {
  112.     int ret = 0;
  113.     while (p)
  114.         if (x <= p->x)
  115.             p = p->ls;
  116.         else {
  117.             ret += p->sz + get_cnt(p->ls);
  118.             p = p->rs;
  119.         }
  120.     return ret;
  121. }
  122.  
  123. inline tre* create(int x) {
  124.     static tre pool[N << 5];
  125.     static tre* p = pool;
  126.     ++p;
  127.     p->x = x;
  128.     p->cnt = p->sz = 1;
  129.     p->rnd = fast_rand();
  130.     return p;
  131. }
  132.  
  133. inline void zig(tre*& p) {
  134.     tre* son = p->ls;
  135.     p->ls = son->rs;
  136.     son->rs = p;
  137.     update(p);
  138.     p = son;
  139.     update(p);
  140. }
  141.  
  142. inline void zag(tre*& p) {
  143.     tre* son = p->rs;
  144.     p->rs = son->ls;
  145.     son->ls = p;
  146.     update(p);
  147.     p = son;
  148.     update(p);
  149. }
  150.  
  151. inline int get_cnt(tre* p)
  152. { return p ? p->cnt : 0; }
  153.  
  154. inline void update(tre* p)
  155. { p->cnt = p->sz + get_cnt(p->ls) + get_cnt(p->rs); }
  156.  
  157. void insert(tre*& p, tre* q) {
  158.     if (!p) {
  159.         p = q;
  160.         return;
  161.     }
  162.     if (q->x <= p->x) {
  163.         insert(p->ls, q);
  164.         update(p);
  165.         if (p->ls->cnt < p->cnt)
  166.             zig(p);
  167.     } else {
  168.         insert(p->rs, q);
  169.         update(p);
  170.         if (p->rs->cnt < p->cnt)
  171.             zag(p);
  172.     }
  173. }
  174.  
  175. void insert(tre*& p, int x) {
  176.     if (!p) {
  177.         p = create(x);
  178.         return;
  179.     }
  180.     if (p->x == x) {
  181.         ++p->sz;
  182.         ++p->cnt;
  183.         return;
  184.     }
  185.     if (x < p->x) {
  186.         insert(p->ls, x);
  187.         update(p);
  188.         if (p->ls->cnt < p->cnt)
  189.             zig(p);
  190.     } else {
  191.         insert(p->rs, x);
  192.         update(p);
  193.         if (p->rs->cnt < p->cnt)
  194.             zag(p);
  195.     }
  196. }
  197.  
  198. seg* construct(int l, int r) {
  199.     static seg pool[N << 1];
  200.     static int cnt;
  201.     seg* p = pool + cnt;
  202.     ++cnt;
  203.     p->l = l;
  204.     p->r = r;
  205.     for (int i = l; i <= r; ++i)
  206.         insert(p->root, a[i]);
  207.     if (l == r)
  208.         return p;
  209.     int mid = (l + r) >> 1;
  210.     p->ls = construct(l, mid);
  211.     p->rs = construct(mid + 1, r);
  212.     return p;
  213. }
  214.  
  215. inline int fast_rand() {
  216.     static int x = time(NULL), y = x << 4, z = x >> 2, t;
  217.     x ^= x << 4;
  218.     x ^= x >> 2;
  219.     t = x ^ y ^ z;
  220.     z = y;
  221.     y = x;
  222.     x = t;
  223.     return t;
  224. }
  225.  
  226. inline int get_x(int l, int r, int x) {
  227.     int lx = -100000000, rx = 100000000, mid;
  228.     while (lx < rx) {
  229.         mid = (lx + rx) >> 1;
  230.         if (get_rank(root, l, r, mid) <= x)
  231.             lx = mid + 1;
  232.         else
  233.             rx = mid;
  234.     }
  235.     return lx - 1;
  236. }
  237.  
  238. inline bool remove_x(tre*& p, int x) {
  239.     if (!p)
  240.         return false;
  241.     if (p->x == x) {
  242.         --p->sz;
  243.         --p->cnt;
  244.         if (!p->sz) {
  245.             res1 = p->ls;
  246.             res2 = p->rs;
  247.             p = NULL;
  248.             return true;
  249.         }
  250.         return false;
  251.     }
  252.     if (x < p->x)
  253.         remove(p->ls, x);
  254.     else
  255.         remove(p->rs, x);
  256.     update(p);
  257.     return false;
  258. }
  259.  
  260. inline void change(seg* p, int k, int x) {
  261.     while (p) {
  262.         remove(p->root, a[k]);
  263.         insert(p->root, x);
  264.         if (p->l == p->r)
  265.             return;
  266.         if (k <= p->ls->r)
  267.             p = p->ls;
  268.         else
  269.             p = p->rs;
  270.     }
  271. }
  272.  
  273. inline int prev(tre* p, int x) {
  274.     int ret = -INT_MAX;
  275.     while (p)
  276.         if (p->x < x) {
  277.             ret = max(ret, p->x);
  278.             p = p->rs;
  279.         } else
  280.             p = p->ls;
  281.     return ret;
  282. }
  283.  
  284. inline int post(tre* p, int x) {
  285.     int ret = INT_MAX;
  286.     while (p)
  287.         if (p->x > x) {
  288.             ret = min(ret, p->x);
  289.             p = p->ls;
  290.         } else
  291.             p = p->rs;
  292.     return ret;
  293. }
  294.  
  295. int prev(seg* p, int l, int r, int x) {
  296.     if (p->l == l && p->r == r)
  297.         return prev(p->root, x);
  298.     if (r <= p->ls->r)
  299.         return prev(p->ls, l, r, x);
  300.     if (l >= p->rs->l)
  301.         return prev(p->rs, l, r, x);
  302.     return max(prev(p->ls, l, p->ls->r, x),
  303.                prev(p->rs, p->rs->l, r, x));
  304. }
  305.  
  306. int post(seg* p, int l, int r, int x) {
  307.     if (p->l == l && p->r == r)
  308.         return post(p->root, x);
  309.     if (r <= p->ls->r)
  310.         return post(p->ls, l, r, x);
  311.     if (l >= p->rs->l)
  312.         return post(p->rs, l, r, x);
  313.     return min(post(p->ls, l, p->ls->r, x),
  314.                post(p->rs, p->rs->l, r, x));
  315. }
Advertisement
Add Comment
Please, Sign In to add comment