EntropyIncreaser

Offline Dynamic Connectivity

Mar 16th, 2018
156
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 <limits>
  5. #include <map>
  6.  
  7. using namespace std;
  8.  
  9. const int N = 5010, M = 500010;
  10.  
  11. struct Data {
  12.     int v, id;
  13.    
  14.     Data() {}
  15.    
  16.     Data(int v, int id) : v(v), id(id) {}
  17.    
  18.     bool operator<(const Data& rhs) const {
  19.         return v < rhs.v;
  20.     }
  21. };
  22.  
  23. struct LCT {
  24.     struct Node {
  25.         bool rev;
  26.         Data val, myn;
  27.         union {
  28.             struct {
  29.                 Node *ls, *rs;
  30.             };
  31.             Node* ch[2];
  32.         };
  33.         Node *prt, *path;
  34.        
  35.         bool relation() const {
  36.             return this == prt->rs;
  37.         }
  38.        
  39.         void pushDown() {
  40.             if (rev) {
  41.                 rev = false;
  42.                 swap(ls, rs);
  43.                 if (ls)
  44.                     ls->rev = !ls->rev;
  45.                 if (rs)
  46.                     rs->rev = !rs->rev;
  47.             }
  48.         }
  49.        
  50.         void update() {
  51.             myn = val;
  52.             if (ls)
  53.                 myn = min(myn, ls->myn);
  54.             if (rs)
  55.                 myn = min(myn, rs->myn);
  56.         }
  57.        
  58.         void rotate() {
  59.             if (prt->prt)
  60.                 prt->prt->pushDown();
  61.             prt->pushDown();
  62.             pushDown();
  63.             path = prt->path;
  64.             prt->path = NULL;
  65.             bool f = relation();
  66.             Node* p = prt;
  67.             if (p->prt)
  68.                 p->prt->ch[p->relation()] = this;
  69.             prt = p->prt;
  70.             p->ch[f] = ch[!f];
  71.             if (ch[!f])
  72.                 ch[!f]->prt = p;
  73.             ch[!f] = p;
  74.             p->prt = this;
  75.             p->update();
  76.             update();
  77.         }
  78.        
  79.         void splay() {
  80.             while (prt) {
  81.                 if (!prt->prt)
  82.                     return rotate();
  83.                 prt->prt->pushDown();
  84.                 prt->pushDown();
  85.                 if (relation() == prt->relation()) {
  86.                     prt->rotate();
  87.                     rotate();
  88.                 } else {
  89.                     rotate();
  90.                     rotate();
  91.                 }
  92.             }
  93.         }
  94.        
  95.         void expose() {
  96.             splay();
  97.             pushDown();
  98.             if (rs) {
  99.                 rs->path = this;
  100.                 rs->prt = NULL;
  101.                 rs = NULL;
  102.                 update();
  103.             }
  104.         }
  105.        
  106.         bool splice() {
  107.             splay();
  108.             if (!path)
  109.                 return false;
  110.             path->expose();
  111.             path->rs = this;
  112.             prt = path;
  113.             path = NULL;
  114.             prt->update();
  115.             return true;
  116.         }
  117.        
  118.         void access() {
  119.             expose();
  120.             while (splice());
  121.         }
  122.        
  123.         void evert() {
  124.             access();
  125.             splay();
  126.             rev = !rev;
  127.         }
  128.        
  129.         Data query() {
  130.             access();
  131.             splay();
  132.             return myn;
  133.         }
  134.     };
  135.    
  136.     Node ver[N * 2 + M];
  137.    
  138.     void link(int u, int v) {
  139.         ver[u].evert();
  140.         ver[u].path = ver + v;
  141.     }
  142.    
  143.     void cut(int u, int v) {
  144.         ver[u].evert();
  145.         ver[v].access();
  146.         ver[u].expose();
  147.         ver[v].path = NULL;
  148.     }
  149.    
  150.     Data query(int u, int v) {
  151.         ver[u].evert();
  152.         return ver[v].query();
  153.     }
  154. };
  155.  
  156. int n, m, vCnt;
  157. LCT mst;
  158. int opt[M], x[M], y[M], lst[M];
  159. int eu[N * 2 + M], ev[N * 2 + M];
  160. map<int, int> g[N];
  161.  
  162. int main() {
  163.     scanf("%d%d", &n, &m);
  164.     for (int i = 1; i <= m; ++i) {
  165.         scanf("%d%d%d", &opt[i], &x[i], &y[i]);
  166.     }
  167.     for (int i = m; i; --i) {
  168.         if (x[i] > y[i])
  169.             swap(x[i], y[i]);
  170.         if (opt[i] == 1)
  171.             g[x[i]][y[i]] = i;
  172.         else if (opt[i] == 0) {
  173.             map<int, int>::iterator it = g[x[i]].find(y[i]);
  174.             if (it == g[x[i]].end())
  175.                 lst[i] = numeric_limits<int>::max();
  176.             else {
  177.                 lst[i] = it->second;
  178.                 g[x[i]].erase(it);
  179.             }
  180.         }
  181.     }
  182.     for (int i = 1; i <= n; ++i)
  183.         mst.ver[i].val = mst.ver[i].myn = Data(numeric_limits<int>::max(), i);
  184.     vCnt = n;
  185.     for (int i = 2; i <= n; ++i) {
  186.         ++vCnt;
  187.         mst.ver[vCnt].val = mst.ver[vCnt].myn = Data(0, vCnt);
  188.         mst.link(1, vCnt);
  189.         mst.link(vCnt, i);
  190.         eu[vCnt] = 1;
  191.         ev[vCnt] = i;
  192.     }
  193.     for (int i = 1; i <= m; ++i) {
  194.         if (x[i] > n || y[i] > n) {
  195.             fputs("WA", stderr);
  196.             fprintf(stderr, "%d %d %d\n", i, x[i], y[i]);
  197.             return 0;
  198.         }
  199.         if (opt[i] == 2) {
  200.             Data gt = mst.query(x[i], y[i]);
  201.             puts(gt.v > i ? "Y" : "N");
  202.         } else if (opt[i] == 0) {
  203.             Data gt = mst.query(x[i], y[i]);
  204.             if (gt.v >= lst[i])
  205.                 continue;
  206.             ++vCnt;
  207.             mst.cut(gt.id, eu[gt.id]);
  208.             mst.cut(gt.id, ev[gt.id]);
  209.             mst.ver[vCnt].val = mst.ver[vCnt].myn = Data(lst[i], vCnt);
  210.             mst.link(vCnt, x[i]);
  211.             mst.link(vCnt, y[i]);
  212.             eu[vCnt] = x[i];
  213.             ev[vCnt] = y[i];
  214.         }
  215.     }
  216.     return 0;
  217. }
Advertisement
Add Comment
Please, Sign In to add comment