zoukankan      html  css  js  c++  java
  • 【题解】Luogu P3950 部落冲突

    原题传送门

    一开始先把树中每条边的两端连接

    U操作:把u,v两个点连起来

    C操作:把u,v两个点分开来

    Q操作:判断在这个森林里u的根和v的根是否相等(是否连通)

    #include <bits/stdc++.h>
    #define N 300005
    #define getchar nc
    using namespace std;
    inline char nc(){
        static char buf[100000],*p1=buf,*p2=buf; 
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
    }
    inline int read()
    {
        register int x=0,f=1;register char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*f;
    }
    inline void Swap(register int &a,register int &b)
    {
        a^=b^=a^=b;
    }
    struct Link_Cut_Tree{
    	int c[N][2],fa[N],top,q[N],rev[N];
    	inline bool isroot(register int x)
    	{
    		return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
    	}
    	inline void pushdown(register int x)
    	{
    		if(rev[x])
    		{
    			int l=c[x][0],r=c[x][1];
    			rev[l]^=1,rev[r]^=1,rev[x]^=1;
    			Swap(c[x][0],c[x][1]);
    		}
    	}
    	inline void rotate(register int x)
    	{
    		int y=fa[x],z=fa[y],l,r;
    		l=c[y][0]==x?0:1;
    		r=l^1;
    		if(!isroot(y))
    			c[z][c[z][0]==y?0:1]=x;
    		fa[x]=z;
    		fa[y]=x;
    		fa[c[x][r]]=y;
    		c[y][l]=c[x][r];
    		c[x][r]=y;
    	}
    	inline void splay(register int x)
    	{
    		top=1;
    		q[top]=x;
    		for(register int i=x;!isroot(i);i=fa[i])
    			q[++top]=fa[i];
    		for(register int i=top;i;--i)
    			pushdown(q[i]);
    		while(!isroot(x))
    		{
    			int y=fa[x],z=fa[y];
    			if(!isroot(y))
    				rotate((c[y][0]==x)^(c[z][0]==y)?(x):(y));
    			rotate(x);
    		}
    	}
    	inline void access(register int x)
    	{
    		for(register int t=0;x;t=x,x=fa[x])
    		{
    			splay(x);
    			c[x][1]=t;
    		}
    	}
    	inline void makeroot(register int x)
    	{
    		access(x);
    		splay(x);
    		rev[x]^=1;
    	}
    	inline int findroot(register int x)
    	{
    		access(x);
    		splay(x);
    		while(c[x][0])
    			x=c[x][0];
    		return x;
    	}
    	inline void split(register int x,register int y)
    	{
    		makeroot(x);
    		access(y);
    		splay(y);
    	}
    	inline void cut(register int x,register int y)
    	{
    		split(x,y);
    		c[y][0]=0;
    		fa[x]=0;
    	}
    	inline void link(register int x,register int y)
    	{
    		makeroot(x);
    		fa[x]=y;	
    	}	
    }T;
    int n,m,cnt;
    int a[N],b[N];
    int main()
    {
    	n=read(),m=read();
    	for(register int i=1;i<n;++i)
    	{
    		int u=read(),v=read();
    		T.link(u,v);
    	}
    	while(m--)
    	{
    		char ch=getchar();
    		while(ch!='Q'&&ch!='C'&&ch!='U')
    			ch=getchar();
    		if(ch=='Q')
    		{
    			int x=read(),y=read();
    			puts(T.findroot(x)==T.findroot(y)?"Yes":"No");
    		} 
    		else if(ch=='C')
    		{
    			a[++cnt]=read(),b[cnt]=read();
    			T.cut(a[cnt],b[cnt]);
    		}
    		else
    		{
    			int x=read();
    			T.link(a[x],b[x]);
    		}
    	}
    }
    
  • 相关阅读:
    Array
    StringBuffer
    String
    字节流
    正则表达式
    coursera 机器学习 linear regression 线性回归的小项目
    立个FLAG!
    排序题目练习(Ignatius and the Pincess IV、排序、Clock、排名)
    codeforces 1006
    codeforces
  • 原文地址:https://www.cnblogs.com/yzhang-rp-inf/p/10203241.html
Copyright © 2011-2022 走看看