3673: 可持久化并查集 by zky
Submit: 2724 Solved: 1206
[Submit][Status][Discuss]
Description
n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
0<n,m<=2*10^4
Input
Output
Sample Input
5 6
1 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2
1 1 2
3 1 2
2 0
3 1 2
2 1
3 1 2
Sample Output
1
0
1
0
1
HINT
Source
没错我就是来骗访问量的,
这道题和上一道题的唯一区别就是
不用xor!
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<ext/rope> using namespace std; using namespace __gnu_cxx; const int MAXN=2000050; const int maxn=0x7fffffff; void read(int &n) { char c='+';int x=0;bool flag=0; while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;} while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();} flag==1?n=-x:n=x; } rope<int> *rp[MAXN]; int a[MAXN]; int n,m,how,x,y,lastans; int find(int i,int x) { if(rp[i]->at(x)==x) return x; int f=find(i,rp[i]->at(x)); if(f==rp[i]->at(x)) return f; rp[i]->replace(x,f); return f; } void merge(int i,int x,int y) { x=find(i,x),y=find(i,y); if(x!=y) rp[i]->replace(y,x); } int main() { int n,m; read(n);read(m); for(int i=1;i<=n;i++) a[i]=i; rp[0]=new rope<int> (a,a+n+1); for(int i=1;i<=m;i++) { rp[i]=new rope<int> (*rp[i-1]); int how;read(how); if(how==1) { read(x);read(y); merge(i,x^lastans,y^lastans); } else if(how==2) { read(x); rp[i]=rp[x^lastans]; } else if(how==3) { read(x);read(y); printf("%d\n",(find(i,x^lastans)==find(i,y^lastans))); } } return 0; }
作者:自为风月马前卒
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。