思路
- 题意:一共有三种操作:
- ①:合并x和y
- ②:合并[x , y]的所有数
- ③:查询x和y在不在同一个连通块里面
- 做法:第二个操作如果直接暴力会T,所以要优化一下,假设x和x+1,x+2已经再一个连通块里面了,就不用再每一个都去做①的操作了,所以就可以优化这个部分,我们记录下第一个比x大并且不属于x连通块的点的编号,合并完x,下一步直接跳到那个点,合并那个点即可。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
using namespace std;
typedef struct
{
int r;
int p;
} node;
node a[200005];
int find(int x)
{
int r = x;
while(r!= a[r].p)
{
r = a[r].p;
}
while(a[x].p!= r)
{
int temp = a[x].p;
a[x].p = r;
x = temp;
}
return r;
}
void init(int n)
{
for(int i = 1;i<= n;i++)
{
a[i].p = i;
a[i].r = i+1;
}
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
init(n);
int x,y,o;
while(m--)
{
scanf("%d %d %d",&o,&x,&y);
if(o == 1)
{
a[find(x)].p = a[find(y)].p;
}
else if(o == 2)
{
int fy = a[find(y)].p;
while(x<= y)
{
int temp = a[x].r;
a[find(x)].p = fy;
a[x].r = a[y].r;
x = temp;
}
}
else
{
if(find(x) == find(y))
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}