EntropyIncreaser

LinkCutTree

Mar 1st, 2018
201
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.35 KB | None | 0 0
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <ctime>
  5.  
  6. #include <algorithm>
  7. #include <limits>
  8. #include <numeric>
  9. #include <iostream>
  10.  
  11. #ifdef LBT_DEBUG
  12. #define LOG(FMT...) fprintf(stderr, "[LOG MESSAGE]: " FMT)
  13. #define OUT(X) std::cerr << "[LOG #" #X "]: " << X << std::endl
  14. #else
  15. #define LOG(FMT...)
  16. #define OUT(X)
  17. #endif
  18.  
  19. struct LinkCutTree {
  20.     struct Node {
  21.         int v, sum;
  22.         bool rev;
  23.         union {
  24.             struct {
  25.                 Node *ls, *rs;
  26.             };
  27.             Node* ch[2];
  28.         };
  29.         Node *prt, *path;
  30.  
  31.         bool relation() const {
  32.             return this == prt->rs;
  33.         }
  34.  
  35.         void pushDown() {
  36.             if (rev) {
  37.                 std::swap(ls, rs);
  38.                 if (ls)
  39.                     ls->rev = !ls->rev;
  40.                 if (rs)
  41.                     rs->rev = !rs->rev;
  42.                 rev = false;
  43.             }
  44.         }
  45.  
  46.         void update() {
  47.             sum = v;
  48.             if (ls)
  49.                 sum ^= ls->sum;
  50.             if (rs)
  51.                 sum ^= rs->sum;
  52.         }
  53.  
  54.         void rotate() {
  55.             if (prt->prt)
  56.                 prt->prt->pushDown();
  57.             prt->pushDown();
  58.             pushDown();
  59.             path = prt->path;
  60.             prt->path = NULL;
  61.             bool rel = relation();
  62.             Node* p = prt;
  63.             if (p->prt)
  64.                 p->prt->ch[p->relation()] = this;
  65.             prt = p->prt;
  66.             p->ch[rel] = ch[!rel];
  67.             if (ch[!rel])
  68.                 ch[!rel]->prt = p;
  69.             ch[!rel] = p;
  70.             p->prt = this;
  71.             p->update();
  72.             update();
  73.         }
  74.  
  75.         void splay() {
  76.             while (prt) {
  77.                 if (prt->prt == NULL) {
  78.                     rotate();
  79.                     return;
  80.                 }
  81.                 prt->prt->pushDown();
  82.                 prt->pushDown();
  83.                 if (relation() == prt->relation()) {
  84.                     prt->rotate();
  85.                     rotate();
  86.                 } else {
  87.                     rotate();
  88.                     rotate();
  89.                 }
  90.             }
  91.         }
  92.  
  93.         void expose() {
  94.             splay();
  95.             pushDown();
  96.             if (rs) {
  97.                 rs->prt = NULL;
  98.                 rs->path = this;
  99.                 rs = NULL;
  100.                 update();
  101.             }
  102.         }
  103.  
  104.         bool splice() {
  105.             splay();
  106.             if (!path)
  107.                 return false;
  108.             path->expose();
  109.             path->rs = this;
  110.             prt = path;
  111.             path = NULL;
  112.             prt->update();
  113.             return true;
  114.         }
  115.  
  116.         void access() {
  117.             expose();
  118.             while (splice());
  119.         }
  120.  
  121.         void evert() {
  122.             access();
  123.             splay();
  124.             rev = !rev;
  125.         }
  126.  
  127.         int query() {
  128.             access();
  129.             splay();
  130.             return sum;
  131.         }
  132.     };
  133.  
  134.     static const int N = 300010;
  135.  
  136.     Node vertex[N];
  137.  
  138.     bool linked(int u, int v) {
  139.         vertex[u].evert();
  140.         vertex[v].access();
  141.         vertex[v].splay();
  142.         vertex[v].pushDown();
  143.         return vertex[v].ls == vertex + u;
  144.     }
  145.  
  146.     void link(int u, int v) {
  147.         vertex[v].evert();
  148.         vertex[v].path = vertex + u;
  149.     }
  150.  
  151.     void cut(int u, int v) {
  152.         vertex[u].evert();
  153.         vertex[v].access();
  154.         vertex[v].splay();
  155.         vertex[v].pushDown();
  156.         vertex[v].ls->prt = NULL;
  157.         vertex[v].ls = NULL;
  158.         vertex[v].update();
  159.     }
  160.  
  161.     int query(int u, int v) {
  162.         vertex[u].evert();
  163.         return vertex[v].query();
  164.     }
  165.  
  166.     void update(int u, int x) {
  167.         vertex[u].splay();
  168.         vertex[u].v = x;
  169.         vertex[u].update();
  170.     }
  171. };
  172.  
  173. typedef long long ll;
  174.  
  175. LinkCutTree linkCutTree;
  176.  
  177. int main() {
  178.     int n, m;
  179.     scanf("%d%d", &n, &m);
  180.     for (int i = 1; i <= n; ++i) {
  181.         int x;
  182.         scanf("%d", &x);
  183.         linkCutTree.update(i, x);
  184.     }
  185.     while (m--) {
  186.         int opt, x, y;
  187.         scanf("%d%d%d", &opt, &x, &y);
  188.         switch (opt) {
  189.             case 0:
  190.                 printf("%d\n", linkCutTree.query(x, y));
  191.                 break;
  192.             case 1:
  193.                 if (!linkCutTree.linked(x, y))
  194.                     linkCutTree.link(x, y);
  195.                 break;
  196.             case 2:
  197.                 if (linkCutTree.linked(x, y))
  198.                     linkCutTree.cut(x, y);
  199.                 break;
  200.             case 3:
  201.                 linkCutTree.update(x, y);
  202.                 break;
  203.             default:break;
  204.         }
  205.     }
  206.     return 0;
  207. }
Advertisement
Add Comment
Please, Sign In to add comment