zoukankan      html  css  js  c++  java
  • BZOJ4998 星球联盟

    BZOJ4998 星球联盟


    题目描述

    传送门

    题目分析

    发现题目说白了就是让你动态维护强连通分量。决定使用lct来维护,外面套一个并查集来维护连通性,查的时候直接输出当前集合的大小就可以了。

    是代码呢

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=2e5+7;
    #define lc ch[x][0]
    #define rc ch[x][1]
    int q[MAXN],s[MAXN],size[MAXN],n,m,r[MAXN],st[MAXN],ch[MAXN][2],fa[MAXN],f[MAXN],Q,add[MAXN];
    inline int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
    inline bool nroot(int x){return ch[f[x]][0]==x||ch[f[x]][1]==x;}
    inline void pushr(int x){swap(lc,rc);r[x]^=1;}
    inline void pushup(int x){s[x]=s[lc]+s[rc]+add[x];}
    inline void pushdown(int x)
    {
    	if(r[x]){
    		if(lc) pushr(lc);
    		if(rc) pushr(rc);
    		r[x]=0;
    	}
    }
    inline void rotate(int x)
    {
    	int y=f[x],z=f[y],kind=ch[y][1]==x,w=ch[x][!kind];
    	if(nroot(y)) ch[z][ch[z][1]==y]=x;ch[x][!kind]=y;ch[y][kind]=w;
    	if(w) f[w]=y;f[y]=x;f[x]=z;
    	pushup(y);
    }
    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((ch[y][0]==x)^(ch[z][0]==y)?y:x);
    		rotate(x);
    	}
    	pushup(x);
    }
    inline void access(int x)
    {
    	for(int y=0;x;y=x,x=f[y]=find(f[x]))
    		splay(x),rc=y,pushup(x);
    }
    inline void makeroot(int x)
    {
    	access(x);splay(x);pushr(x);
    }
    inline int findroot(int x)
    {
    	access(x);splay(x);
    	while(lc) pushdown(x),x=lc;
    	splay(x);
    	return x;
    }
    inline void split(int x,int y)
    {
    	makeroot(x);access(y);splay(y);
    }
    inline void merge(int x,int y)
    {
    	if(x==y) return;
    	makeroot(x);
    	if(findroot(y)!=x){
    		f[x]=y;
    		return;
    	}
    	makeroot(y);access(x);splay(x);
    	int cnt=s[x];
    	int L=0,R=0;
    	q[++R]=x;
    	while(L<R){
    		x=q[++L];
    		if(lc) q[++R]=lc;
    		if(rc) q[++R]=rc;
    		fa[x]=y;
    		add[x]=s[x]=f[x]=lc=rc=0;
    	}
    	add[y]=s[y]=cnt;
    	f[y]=0;
    }
    inline int read()
    {
        int x=0,c=1;
        char ch=' ';
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        while(ch=='-')c*=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*c;
    }
    int main()
    {
    	n=read();m=read();Q=read();
    	for(int i=1;i<=n;i++){
    		add[i]=s[i]=1;fa[i]=i;
    	}
    	for(int i=1;i<=m;i++){
    		int x=read(),y=read();
    		x=find(x),y=find(y);
    		merge(x,y);
    	}
    	for(int i=1;i<=Q;i++){
    		int x=read(),y=read();
    		x=find(x);y=find(y);
    		if(x==y){
    			printf("%d
    ",add[x]);
    			continue;
    		}
    		makeroot(x);
    		if(findroot(y)!=x){
    			f[x]=y;
    			puts("No");
    			continue;
    		}
    		makeroot(y);access(x);splay(x);
    		int cnt=s[x];
    		int L=0,R=0;
    		q[++R]=x;
    		while(L<R){
    			x=q[++L];
    			if(lc) q[++R]=lc;
    			if(rc) q[++R]=rc;
    			fa[x]=y;
    			add[x]=s[x]=f[x]=lc=rc=0;
    		}
    		add[y]=s[y]=cnt;f[y]=0;
    		printf("%d
    ",add[y]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    利用idea里面的mysql插件进行导入sql文件
    JSTL标签
    deepin20系统下配置JAVA开发环境
    deepin20安装及问题解决
    SpringBoot 在项目启之后执行自定义方法的两种方式
    Nick 的经验书
    Java 经验书
    SpringBoot 经验书
    Linux 经验书
    在MacOS中启动SSH服务
  • 原文地址:https://www.cnblogs.com/victorique/p/10210699.html
Copyright © 2011-2022 走看看