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);
      }
    }
    
  • 相关阅读:
    shell数组
    Apache HTTP Server 与 Tomcat 的三种连接方式介绍
    实现Java动态类载入机制
    Tomcat 阀
    MYSQL 常用命令
    MYSQL字符数字转换
    主题:MySQL数据库操作实战
    日本手机三大代理商的UA
    Java解析XML文档——dom解析xml (转载)
    MS sql server和mysql中update多条数据的例子
  • 原文地址:https://www.cnblogs.com/dixiao/p/14736760.html
Copyright © 2011-2022 走看看