Description
一开始有 (n) 个元素,可以进行几个操作.
合并 (x,y) .
合并 (x,x+1,...,y) .
询问 (x,y) 是否在一个集合中.
Sol
并查集+链表.
第二个询问,一直用链表找 (pre) 优化一下就可以了.
另外 51Nod 1525 重组公司.
Code
#include<cstdio> #include<utility> #include<algorithm> #include<iostream> using namespace std; const int N = 200005; int n,q; int f[N],pre[N]; inline int in(int x=0,char ch=getchar()){ while(ch>'9' || ch<'0') ch=getchar(); while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x; } int find(int x){ return f[x]==x?x:f[x]=find(f[x]); } int main(){ n=in(); for(int i=1;i<=n;i++) f[i]=i,pre[i]=i-1; for(int q=in(),t,x,y,r1,r2;q--;){ t=in(),x=in(),y=in(); switch(t){ case 1:x=find(x),y=find(y),f[y]=x;break; case 2: for(r1=find(x),r2=y;y>=x;y=pre[y]) f[find(y)]=r1; pre[r2]=y;break; default:if((x=find(x)) == (y=find(y))) puts("YES"); else puts("NO");break; } }return 0; }