566D

来源:互联网 发布:mac office 登陆激活 编辑:程序博客网 时间:2024/06/06 18:13

题意:并查集两点之间合并和一个区间中所有点合并。查询两点是否在同一集合里

思路:前者直接合并,后者由于是一个区间段,区间所在集合编号确定。下次这个区间再有合并操作了,直接拿区间编号合并。所以用个数组记录,当前集合下一个集合的编号。

#include<cstdio>using namespace std;const int maxn = 2*1e5+10;int f[maxn],a[maxn];//a[i]指向下一个与i不在同一集合里的人void init(int n){for(int i=1;i<=n;i++)f[i]=i,a[i]=i+1;}int Find(int x){if(f[x]==x)return x;else return f[x]=Find(f[x]);}void Union(int x,int y){int xx=Find(x);int yy=Find(y);if(xx!=yy)f[xx]=yy;}int main(){int n,m;while(~scanf("%d%d",&n,&m)){init(n);int op,x,y;while(m--){scanf("%d%d%d",&op,&x,&y);if(op==1)Union(x,y);else if(op==2){int temp;for(int i=x+1;i<=y;i=temp){Union(i-1,i);temp=a[i];a[i]=y+1;}}else{if(Find(x)==Find(y))printf("YES\n");elseprintf("NO\n");}}}}

原创粉丝点击