zoukankan      html  css  js  c++  java
  • 题解 洛谷P2147/BZOJ2049【[SDOI2008]洞穴勘测】

    没有要求维护点权,只需要维护点的连通性即可。

    就是朴素的LCT,居然还不要pushup。

    感觉有些不适应啊.......不得不说LCT是个神器。

    简单分析一下。

    • 对于每种命令:
      • 如果是Connect x y (链接 x y):直接 link(x,y)即可。

      • 如果是Destroy x y (切断 x y):直接 cut(x,y)即可。

      • 如果是Query x y (询问 x y 的连通性):判断findroot(x)findroot(y)是否一致,一致输出Yes,否则输出No

    然后就A了.......

    Code:

    #include<bits/stdc++.h>
    #define ll long long
    #define inf 0x3f3f3f3f
    #define RI register int
    #define A printf("A")
    #define C printf(" ") 
    using namespace std;
    const int N=2e5+2;
    template <typename Tp> inline void IN(Tp &x){
        int f=1;x=0;char ch=getchar();
        while(ch<'0'||ch>'9')if(ch=='-')f=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();x*=f;
    }int n,m,f[N],r[N],hep[N],ch[N][2];
    inline int chk(int x){return ch[f[x]][1]==x;}
    inline int get(int x){return ch[f[x]][0]==x||ch[f[x]][1]==x;}
    inline void filp(int x){swap(ch[x][0],ch[x][1]);r[x]^=1;} 
    inline void pushdown(int x){
    	if(!r[x])return;r[x]=0;
    	if(ch[x][0])filp(ch[x][0]);
    	if(ch[x][1])filp(ch[x][1]);
    }
    inline void rotate(int x){
    	int y=f[x],z=f[y],k=chk(x),&v=ch[x][!k];
    	if(get(y))ch[z][chk(y)]=x;v=y,ch[y][k]=v;
    	if(v)f[v]=y;f[y]=x,f[x]=z;return;
    }
    inline void Splay(int x){
    	int y=x,top=0;hep[++top]=y;
    	while(get(y))hep[++top]=y=f[y];
    	while(top)pushdown(hep[top--]);
    	while(get(x)){
    		y=f[x],top=f[y];
    		if(get(y))rotate((ch[y][0]==x)^(ch[top][0]==y)?x:y);
    		rotate(x);
    	}return;
    } 
    inline void Access(int x){
        for(register int y=0;x;x=f[y=x])
           Splay(x),ch[x][1]=y;
    }
    inline void makeroot(int x){
        Access(x);Splay(x);filp(x);
    }
    inline int findroot(int x){
        Access(x);Splay(x);
        while(ch[x][0])pushdown(x),x=ch[x][0];
        return 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[x]==y&&!ch[x][1]){
            f[x]=ch[y][0]=0;
        }return;
    }char op[10];
    int main(){
        scanf("%d%d",&n,&m);
        for(register int x,y,i=1;i<=m;++i){
        	scanf("%s%d%d",op,&x,&y);
            if(op[0]=='C')link(x,y);
    		else if(op[0]=='D')cut(x,y);
    		else if(op[0]=='Q'){
    			if(findroot(x)==findroot(y))printf("Yes
    ");
    			else printf("No
    ");
    		}	
    	}return 0;
    }
    
  • 相关阅读:
    创建者模式 -- 单例模式(反射&序列化)
    设计模式(总)
    并不是static final 修饰的变量都是编译期常量
    内部类和静态内部类的加载顺序
    所有的Java虚拟机必须实现在每个类或接口被Java程序 “ 首次主动使用 ” 时才初始化他们
    24 shell 管道命令与过滤器
    26 bash shell中的信号
    25 Linux中的信号
    23 shell 进程替换
    22 shell组命令与子进程
  • 原文地址:https://www.cnblogs.com/K-Qiuly/p/10273906.html
Copyright © 2011-2022 走看看