题意:
1 a b 合并a,b所在集合
2 k 回到第k次操作之后的状态(查询算作操作)
3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
rope按秩合并:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<ext/rope>
#define pii pair<int,int>
#define N 200005
using namespace std;
using namespace __gnu_cxx;
rope<pii> *his[N];
pii a[N];
pii find(int x,int root)
{
pii fa=his[root]->at(x);
if(fa.first!=x)return find(fa.first,root);
return fa;
}
int main()
{
int n,m,last=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
a[i].first=i,a[i].second=0;
his[0]=new rope<pii>(a,a+n+1);
for(int i=1;i<=m;i++)
{
int op;
scanf("%d",&op);
if(op==1)
{
int a,b;
scanf("%d%d",&a,&b);
a^=last,b^=last;
pii u=find(a,i-1);
pii v=find(b,i-1);
his[i]=new rope<pii>(*his[i-1]);
if(u.first==v.first)continue;
if(u.second<v.second)swap(u,v);
if(u.second==v.second)his[i]->replace(u.first,make_pair(u.first,u.second+1));
his[i]->replace(v.first,make_pair(u.first,v.second));
}
if(op==2)
{
int k;
scanf("%d",&k);
k^=last;
his[i]=new rope<pii>(*his[k]);
}
if(op==3)
{
int a,b;
scanf("%d%d",&a,&b);
a^=last,b^=last;
pii u=find(a,i-1);
pii v=find(b,i-1);
his[i]=new rope<pii>(*his[i-1]);
printf("%d\n",u.first==v.first);
last=u.first==v.first;
}
}
}
rope路径压缩:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<ext/rope>
#define pii pair<int,int>
#define N 200005
using namespace std;
using namespace __gnu_cxx;
rope<int>*his[N];
int find(int x,int root)
{
if(x==his[root]->at(x))return x;
int t=find(his[root]->at(x),root);
if(t!=his[root]->at(x))his[root]->replace(x,t);//不判的话会mle
return his[root]->at(x);
}
int main()
{
int n,m,last=0;
scanf("%d%d",&n,&m);
his[0]=new rope<int>;
his[0]->push_back(0);
for(int i=1;i<=n;i++)his[0]->push_back(i);
for(int i=1;i<=m;i++)
{
int op,a,b,u,v,k;
scanf("%d",&op);
if(op==1)
{
scanf("%d%d",&a,&b);
a^=last,b^=last;
u=find(a,i-1);
v=find(b,i-1);
his[i]=new rope<int>(*his[i-1]);
if(u==v)continue;
his[i]->replace(v,u);
}
if(op==2)
{
scanf("%d",&k);
k^=last;
his[i]=new rope<int>(*his[k]);
}
if(op==3)
{
scanf("%d%d",&a,&b);
a^=last,b^=last;
u=find(a,i-1);
v=find(b,i-1);
his[i]=new rope<int>(*his[i-1]);
printf("%d\n",u==v);
last=u==v;
}
}
}