EntropyIncreaser

Scapegoat Tree

Feb 22nd, 2018
711
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.74 KB | None | 0 0
  1. #include <cstdio>
  2.  
  3. #include <algorithm>
  4. #include <iostream>
  5.  
  6. #define ERRF(FMT...) // fprintf(stderr, FMT)
  7.  
  8. struct ScapegoatTree {
  9.     struct Node {
  10.         int key, w;
  11.         Node *ls, *rs;
  12.     };
  13.  
  14.     static const int N = 100010;
  15.     static const double ALPHA = 0.6;
  16.  
  17.     Node* root;
  18.     Node** scapegoatNode;
  19.  
  20.     static Node* create(int key) {
  21.         static Node pool[N];
  22.         static Node* p = pool;
  23.         p->key = key;
  24.         p->w = 2;
  25.         return p++;
  26.     }
  27.  
  28.     static int get_w(Node* p) {
  29.         return p ? p->w : 1;
  30.     }
  31.  
  32.     static void printLine(Node* p, Node** line) {
  33.         if (!p)
  34.             return;
  35.         printLine(p->ls, line);
  36.         line[get_w(p->ls) - 1] = p;
  37.         printLine(p->rs, line + get_w(p->ls));
  38.     }
  39.  
  40.     static Node* build(Node** begin, Node** end) {
  41.         if (begin == end)
  42.             return NULL;
  43.         Node** mid = begin + (end - begin) / 2;
  44.         Node* p = *mid;
  45.         p->ls = build(begin, mid);
  46.         p->rs = build(mid + 1, end);
  47.         p->w = get_w(p->ls) + get_w(p->rs);
  48.         return p;
  49.     }
  50.  
  51.     static void scapegoat(Node** p) {
  52.         ERRF("SCAPEGOAT %d NODES\n", (*p)->w - 1);
  53.         static Node* line[N];
  54.         printLine(*p, line);
  55.         Node* tmp = build(line, line + (*p)->w - 1);
  56.         *p = tmp;
  57.     }
  58.  
  59.     void recursionInsert(Node*& p, int key) {
  60.         if (!p) {
  61.             p = create(key);
  62.             return;
  63.         }
  64.         ++p->w;
  65.         if (key < p->key)
  66.             recursionInsert(p->ls, key);
  67.         else
  68.             recursionInsert(p->rs, key);
  69.         if (std::max(get_w(p->ls), get_w(p->rs)) >= ALPHA * p->w)
  70.             scapegoatNode = &p;
  71.     }
  72.  
  73.     void recursionErase(Node*& p, int key) {
  74.         if (p->key == key) {
  75.             Node** q = &p->ls;
  76.             if (!*q) {
  77.                 p = p->rs;
  78.                 return;
  79.             }
  80.             if (!(*q)->rs) {
  81.                 (*q)->rs = p->rs;
  82.                 p = *q;
  83.                 p->w = get_w(p->ls) + get_w(p->rs);
  84.                 return;
  85.             }
  86.             while ((*q)->rs) {
  87.                 --(*q)->w;
  88.                 q = &(*q)->rs;
  89.             }
  90.             Node* tmp = *q;
  91.             *q = tmp->ls;
  92.             tmp->ls = p->ls;
  93.             tmp->rs = p->rs;
  94.             p = tmp;
  95.             p->w = get_w(p->ls) + get_w(p->rs);
  96.             return;
  97.         }
  98.         --p->w;
  99.         if (key < p->key)
  100.             recursionErase(p->ls, key);
  101.         else
  102.             recursionErase(p->rs, key);
  103.         if (std::max(get_w(p->ls), get_w(p->rs)) >= ALPHA * p->w)
  104.             scapegoatNode = &p;
  105.     }
  106.  
  107.     void insert(int key) {
  108.         scapegoatNode = NULL;
  109.         recursionInsert(root, key);
  110.         if (scapegoatNode)
  111.             scapegoat(scapegoatNode);
  112.     }
  113.  
  114.     void erase(int key) {
  115.         scapegoatNode = NULL;
  116.         recursionErase(root, key);
  117.         if (scapegoatNode)
  118.             scapegoat(scapegoatNode);
  119.     }
  120.  
  121.     int at(int k) const {
  122.         Node* p = root;
  123.         while (p) {
  124.             if (k == get_w(p->ls))
  125.                 return p->key;
  126.             if (k < get_w(p->ls))
  127.                 p = p->ls;
  128.             else {
  129.                 k -= get_w(p->ls);
  130.                 p = p->rs;
  131.             }
  132.         }
  133.         return 0;
  134.     }
  135.  
  136.     int rank(int key) const {
  137.         int ret = 1;
  138.         Node* p = root;
  139.         while (p) {
  140.             if (p->key < key) {
  141.                 ret += get_w(p->ls);
  142.                 p = p->rs;
  143.             } else
  144.                 p = p->ls;
  145.         }
  146.         return ret;
  147.     }
  148.  
  149.     int prev(int key) const {
  150.         int ret = 0;
  151.         Node* p = root;
  152.         while (p) {
  153.             if (p->key < key) {
  154.                 ret = p->key;
  155.                 p = p->rs;
  156.             } else
  157.                 p = p->ls;
  158.         }
  159.         return ret;
  160.     }
  161.  
  162.     int post(int key) const {
  163.         int ret = 0;
  164.         Node* p = root;
  165.         while (p) {
  166.             if (p->key > key) {
  167.                 ret = p->key;
  168.                 p = p->ls;
  169.             } else
  170.                 p = p->rs;
  171.         }
  172.         return ret;
  173.     }
  174. } scapegoatTree;
  175.  
  176. const int N = 100010;
  177.  
  178. int main() {
  179. //  freopen("test.in", "r", stdin);
  180.     int n;
  181.     scanf("%d", &n);
  182.     while (n--) {
  183.         int opt, x;
  184.         scanf("%d%d", &opt, &x);
  185.         ERRF("%d %d\n", opt, x);
  186.         switch (opt) {
  187.             case 1:
  188.                 scapegoatTree.insert(x);
  189.                 break;
  190.             case 2:
  191.                 scapegoatTree.erase(x);
  192.                 break;
  193.             case 3:
  194.                 printf("%d\n", scapegoatTree.rank(x));
  195.                 break;
  196.             case 4:
  197.                 printf("%d\n", scapegoatTree.at(x));
  198.                 break;
  199.             case 5:
  200.                 printf("%d\n", scapegoatTree.prev(x));
  201.                 break;
  202.             case 6:
  203.                 printf("%d\n", scapegoatTree.post(x));
  204.                 break;
  205.             default:break;
  206.         }
  207.     }
  208.     return 0;
  209. }
Advertisement
Add Comment
Please, Sign In to add comment