扩张并查集求一组hack
查看原帖
扩张并查集求一组hack
448897
Ctrl加C楼主2023/12/1 22:08
#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N=1e6+5;

inline int read(){
	int x=0,f=1;
	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();
	}
	return x*f;
}

int n,m,c,t,a[2*N+1000],fa[2*N+1000],ans;//1-n T域;n+1~2n F域;2n+1-3n U域

int find(int x){
	if(x==fa[x])return x;
	return fa[x]=find(fa[x]);
}

void merge(int x,int y){
	int xx=find(x),yy=find(y);
	if(xx==yy)return;
	fa[xx]=yy;
}

signed main(){
	c=read(),t=read();
	while(t--){
		n=read(),m=read();
		ans=0;
		for(int i=1;i<=2*n+50;++i)fa[i]=i,a[i]=i;
		for(int i=1;i<=m;++i){
			char opt;
			cin>>opt;
			if(opt=='T'){
				int idq=read();
				a[idq]=2*n+1;
				a[idq+n]=2*n+2;
			}
			if(opt=='F'){
				int idq=read();
				a[idq]=2*n+2;
				a[idq+n]=2*n+1;
			}
			if(opt=='U'){
				int idq=read();
				a[idq]=2*n+3;
				a[idq+n]=2*n+3;
			}
			if(opt=='+'){
				int idq=read(),idp=read();
				a[idq]=a[idp];
				a[idq+n]=a[idp+n];
			}
			if(opt=='-'){
				int idq=read(),idp=read();
				a[idq]=a[idp+n];
				a[idq+n]=a[idp];
			}
		}
		for(int i=1;i<=n;++i){
			if(a[i]>=1&&a[i]<=n){//同类
				merge(i,a[i]);
				merge(i+n,a[i]+n);
			}
			if(a[i]>n&&a[i]<=2*n){//相反
				merge(i,a[i]);
				merge(i+n,a[i]-n);
			}
			if(a[i]==2*n+1){
				merge(i,2*n+1);
				merge(i+n,2*n+2);
			}
			if(a[i]==2*n+2){
				merge(i,2*n+2);
				merge(i+n,2*n+1);
			}
			if(a[i]==2*n+3){
				merge(i,2*n+3);
				merge(i+n,2*n+3);
			}
		}
		for(int i=1;i<=n;++i){
			int x=find(i),y=find(i+n);
			if(x==y)ans++;
		}
		printf("%lld\n",ans);
	}
	return 0;
}
2023/12/1 22:08
加载中...