n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
0<n,m<=2*10^4
标签:color gnu out pre cpp discuss ffffff void 可持久化并查集
n个集合 m个操作
操作:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
0<n,m<=2*10^4
#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; }
标签:color gnu out pre cpp discuss ffffff void 可持久化并查集
原文地址:http://www.cnblogs.com/zwfymqz/p/7327417.html