Advertisement
Guest User

LinkCut

a guest
Oct 11th, 2012
1,041
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.15 KB | None | 0 0
  1. // Author: Pavel Kunyavskiy
  2.  
  3. #include <iostream>
  4. #include <cstdio>
  5.  
  6. using namespace std;
  7.  
  8. const int MAXN = 110000;
  9.  
  10. struct _node;
  11. typedef _node* node;
  12.  
  13. struct _node{
  14.     static node null;
  15.     node l,r,p;
  16.     int size;
  17.     bool rev;
  18.     node pp;
  19.     _node(){
  20.         l = r = p = pp = _node::null;
  21.         size = 1;
  22.         rev = 0;
  23.     }
  24.     _node(void*){
  25.         l = r = p = pp = this;
  26.         size = rev = 0;
  27.     }
  28.     void push(){
  29.         if (rev){
  30.             l->rev ^= 1;
  31.             r->rev ^= 1;
  32.             rev = 0;
  33.             swap(l,r);
  34.         }
  35.     }
  36.     void update(){
  37.         size = (this != null) + l->size + r->size;
  38.         l->p = r->p = this;
  39.     }
  40. };
  41.                                    
  42. node _node::null = new _node(NULL);
  43.  
  44. _node mem[MAXN];
  45. node v2n[MAXN];
  46.  
  47. void rotate(node v){
  48.     node u = v->p;    
  49.     if (v == u->l){
  50.        u->l = v->r;
  51.        v->r = u;
  52.     }
  53.     else {
  54.        u->r = v->l;
  55.        v->l = u;
  56.     }          
  57.     swap(u->p,v->p);
  58.     swap(v->pp,u->pp);
  59.     if (v->p != _node::null){
  60.         if (v->p->r == u)
  61.             v->p->r = v;
  62.         else
  63.             v->p->l = v;
  64.     }                  
  65.     u->update();
  66.     v->update();
  67. }
  68.  
  69. void bigRotate(node v){
  70.     v->p->p->push();
  71.     v->p->push();
  72.     v->push();
  73.     if (v->p->p == _node::null)
  74.         rotate(v);
  75.     else if ((v->p->l == v) ^ (v->p->p->r == v->p))
  76.         rotate(v->p), rotate(v);
  77.     else
  78.         rotate(v), rotate(v);
  79. }
  80.  
  81. inline void Splay(node v){
  82.      while (v->p != _node::null)
  83.         bigRotate(v);
  84. }
  85.  
  86. inline void splitAfter(node v){
  87.     v->push();
  88.     Splay(v);
  89.     v->r->p = _node::null;
  90.     v->r->pp = v;
  91.     v->r = _node::null;
  92.     v->update();
  93. }
  94.  
  95. void expose(int x){
  96.    node v = v2n[x];
  97.    splitAfter(v);
  98.    while (v->pp != _node::null){
  99.        splitAfter(v->pp);
  100.        v->pp->r = v;
  101.        v->pp->update();
  102.        v = v->pp;
  103.        v->r->pp = _node::null;        
  104.    }
  105.    Splay(v2n[x]);
  106. }
  107.  
  108. inline void makeRoot(int x){
  109.     expose(x);
  110.     v2n[x]->rev ^= 1;
  111. }
  112.  
  113. inline void link(int x,int y){
  114.     makeRoot(x);
  115.     makeRoot(y);
  116.     v2n[x]->pp = v2n[y];
  117. }
  118.  
  119. inline void cut(int x,int y){
  120.     expose(x);
  121.     Splay(v2n[y]);
  122.     if (v2n[y]->pp != v2n[x]){
  123.         swap(x,y);
  124.         expose(x);
  125.         Splay(v2n[y]);
  126.     }
  127.     v2n[y]->pp = _node::null;
  128. }
  129.  
  130. inline int get(int x,int y){
  131.     if (x == y)
  132.         return 0;
  133.     makeRoot(x);                        
  134.     expose(y);                          
  135.     expose(x);
  136.     Splay(v2n[y]);
  137.     if (v2n[y]->pp != v2n[x]) return -1;
  138.     return v2n[y]->size;
  139. }            
  140.  
  141. int main(){
  142.     freopen("linkcut.in","r",stdin);
  143.     freopen("linkcut.out","w",stdout);
  144.  
  145.     int n,m;
  146.     scanf("%d %d",&n,&m);
  147.  
  148.     for (int i = 0; i < n; i++)
  149.         v2n[i] = &mem[i];
  150.  
  151.     for (int i = 0; i < m; i++){
  152.         int a,b;
  153.         if (scanf(" link %d %d",&a,&b) == 2)
  154.             link(a-1,b-1);
  155.         else if (scanf(" cut %d %d",&a,&b) == 2)
  156.             cut(a-1,b-1);
  157.         else if (scanf(" get %d %d",&a,&b) == 2)
  158.             printf("%d\n",get(a-1,b-1));
  159.     }                                        
  160.     return 0;
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement