给n组操作,每组操作形式为x y p。

当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。

当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。

输入
输入一个数n表示操作的次数(n<=110^5)
接下来n行每行三个数x,y,p(x,y<=1
10^8,p=0 or 1)
输出
对于n行操作,分别输出n行YES或者NO

输入样例
3
1 2 1
1 3 1
2 3 0

输出样例
YES
YES
NO


在相等的时候很好维护,直接并查集即可,但是不相等时怎么办呢?

用set维护就可以了,set里面存的与当前不能相等的,每次操作一时,判断一下即可,再维护一下set。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int f[N],n,a[N],x[N],y[N],p[N],cnt,m;
set<int> st[N];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
signed main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		scanf("%d %d %d",&x[i],&y[i],&p[i]);	a[++cnt]=x[i],a[++cnt]=y[i];
	}
	sort(a+1,a+1+cnt);	m=unique(a+1,a+1+cnt)-a-1;
	for(int i=1;i<=m;i++)	f[i]=i;
	for(int i=1;i<=n;i++){
		x[i]=lower_bound(a+1,a+1+m,x[i])-a;
		y[i]=lower_bound(a+1,a+1+m,y[i])-a;
	}
	for(int i=1;i<=n;i++){
		if(p[i]){
			int fa=find(x[i]),fb=find(y[i]);
			if(st[fa].find(fb)!=st[fa].end())	puts("NO");
			else if(fa!=fb){
				puts("YES");
				if(st[fa].size()>st[fb].size())	swap(fa,fb);	f[fa]=fb;
				for(auto i=st[fa].begin();i!=st[fa].end();i++){
					st[*i].erase(fa); st[fb].insert(*i); st[*i].insert(fb);
				}
			}else	puts("YES");
		}else{
			int fa=find(x[i]),fb=find(y[i]);
			if(fa!=fb){
				st[fa].insert(fb);	st[fb].insert(fa); puts("YES");
			}else	puts("NO");
		}
	}
	return 0;
}