zoukankan      html  css  js  c++  java
  • [SDOI2008]洞穴勘测

    \(LCT\)裸题。
    不过区别于弹飞绵羊,这题要维护的树的形态,以及查询原根操作。
    请记住,千万不要打错宏定义。

    [SDOI2008]洞穴勘测
    #include<iostream>
    #include<cstdio>
    #define ll long long
    #define N 300005
    
    ll f[N],c[N][2],v[N],r[N],st[N],s[N];
    
    #define lc c[x][0]
    #define rc c[x][1]
    #define l(x) c[x][0]
    #define r(x) c[x][1]
    #define f(x) f[x]
    #define R register int
    #define I inline void
    
    inline bool nroot(int x){return (l(f(x)) == x) || (r(f(x)) == x);}
    
    inline void pushr(int x){std::swap(l(x),r(x));r[x] ^= 1;}
    
    inline void pushdown(int x){
      if(r[x]){
      	if(l(x))
      	pushr(l(x));
      	if(r(x))
      	pushr(r(x));
      	r[x] = 0;
      }
    }
    
    inline void rotate(int x){
      int y = f(x),z = f(y),k = c[y][1] == x,w = c[x][!k];
      if(nroot(y))c[z][r(z) == y] = x;c[x][!k] = y,c[y][k] = w;
      if(w)f(w) = y;f(y) = x;f(x) = z;
    }
    inline void splay(int x){
      int y = x,z = 0;
      st[++z] = y;
      while(nroot(y))st[++z] = y = f(y);
      while(z)pushdown(st[z--]);
      while(nroot(x)){
      	y = f(x),z = f(y);
      	if(nroot(y))
      	rotate(((l(y) == x) ^ (l(z) == y)) ? x : y);
      	rotate(x);
      }
    }
    
    inline void access(int x){
      for(int y = 0;x;x = f(y = x))
      splay(x),r(x) = y;
    }
    
    inline int findroot(int x){
      access(x);splay(x);
      while(l(x))pushdown(x),x = l(x);
      splay(x);
      return x;
    }
    
    inline void makeroot(int x){
      access(x);splay(x);
      pushr(x);
    }
    
    inline void split(int x,int y){
      makeroot(x);
      access(y);splay(y);
    }
    
    inline void link(int x,int y){
      makeroot(x);
      if(findroot(y) != x)
      f(x) = y;
    }
    
    inline void cut(int x,int y){
      makeroot(x);
      if(findroot(y) == x && f(y) == x&&!l(y)){
      	f(y) = r(x) = 0;
      }
    }
    
    ll n,m;
    
    int main(){
      scanf("%lld%lld",&n,&m);
      while(m -- ){
      	char opt[10];
      	ll x,y;
      	scanf("%s%lld%lld",opt,&x,&y);
      	if(opt[0] == 'Q'){
      		if(findroot(x) == findroot(y))
      		puts("Yes");
      		else
      		puts("No");
      	}
      	if(opt[0] == 'C'){
      		link(x,y);
      	}
      	if(opt[0] == 'D')
      	cut(x,y);
      }
    }
    
  • 相关阅读:
    Balanced Binary Tree
    Convert Sorted List to Binary Search Tree
    Convert Sorted Array to Binary Search Tree
    Binary Tree Zigzag Level Order Traversal
    Validate Binary Search Tree
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Maximum Depth of Binary Tree
    如何把U盘的两个盘或者多个盘合成一个
    bugku 想蹭网先解开密码
  • 原文地址:https://www.cnblogs.com/dixiao/p/14736760.html
Copyright © 2011-2022 走看看