并查集

题目链接:https://ac.nowcoder.com/acm/contest/103867/J

题意:

要求1.合并l和r的集合2.判断l~r之间的所有数是否在同一个集合内

思路:

并查集启发式合并
大概就是普通并查集在合并时需要 小集合 并到 大集合 里
然后维护nxt数组,如果与右边连通则指向右边的点,如果不连通指向自己
时间复杂度O(nlogn)

int n,m;
int nxt[maxn];
int find(int x){
	if(nxt[x]!=x){
		nxt[x]=find(nxt[x]);
	}
	return nxt[x];
}
int fa[maxn];
vector<int>v[maxn];
void solve(){
	cin>>n>>m;
	rep(i,1,n){
		fa[i]=i;
		nxt[i]=i;
		v[i].pb(i);
	}
	rep(i,1,m){
		int op,l,r;cin>>op>>l>>r;
		if(op==1){
			int f1=fa[l],f2=fa[r];
			if(f1==f2)continue;
			if(v[f1].size()>v[f2].size())swap(f1,f2);
			for(int x:v[f1]){
				if(fa[x-1]==f2)nxt[x-1]=x;
				if(fa[x+1]==f2)nxt[x]=x+1;
				fa[x]=f2;
				v[f2].pb(x);
			}
			v[f1].clear();
		}else{
			if(find(l)>=r){
				cout<<"YES"<<endl;
			}else cout<<"NO"<<endl;
		}
	}	
}
posted @ 2025-04-10 19:45  Marinaco  阅读(14)  评论(0)    收藏  举报
//雪花飘落效果