题目链接https://cn.vjudge.net/problem/CodeForces-566D
题目大意:
一共有n个单点集,三种操作:
type1 x y代表:合并x和y所在集合
type2 x y代表 :合并x,x+1,…,y-1,y(x到y的区间)所在集合
type3 x y代表 :查询x和y是否在同一集合 是 输出YES, 否 输出NO
思路:暴力合并会超时,需要加个优化,nex数组表示:不属于这个集合的第一个编号,把nex数组初始化为nex[i]=i+1,区间合并的时候,把区间[x,y]中所有点的nex[i]值全部更新为nex[y]的值,下次再合并到这个区间,就可以直接跳过这段, 省了好多时间
AC代码
#include<bits/stdc++.h>
using namespace std;
int n, q;
int p[200005], nex[200005]; ///nex数组记录第一个不属于这个集合的数
int mergee(int x)
{
if(p[x] != x)
p[x] = mergee(p[x]);
return p[x];
}
int main()
{
while(scanf("%d%d", &n, &q)!=EOF)
{
for(int i = 1; i <= n; i++)
p[i] = i, nex[i] = i+1;
while(q--)
{
int a, x, y, to;
scanf("%d%d%d", &a, &x, &y);
if(a == 1) p[mergee(y)] = mergee(x);
else if(a == 2)
{
for(int i = x+1; i <= y; i = to)
{
p[mergee(i)] = mergee(i-1);
to = nex[i];
nex[i] = nex[y];
}
}
else
{
if(mergee(x)!=mergee(y))printf("NO\n");
else printf("YES\n");
}
}
}
return 0;
}