就是一道很水的并查集,只不过要启发式合并罢了
#include <cstdio>
#include <algorithm>
using namespace std;
int fa[100050];
int s[100050];
int dis[100050];
int u,v,ans,maxans;
int x,y,n,m,un,t,fu,fv,lenu,lenv;
int findfather(int x){
return fa[x]==x?x:findfather(fa[x]);
}
void Union(int x,int y,int k){
if (s[x]==s[y]){
fa[x]=y;
dis[x]=k;
s[y]++;
}
else if (s[x]<s[y]){
fa[x]=y;
dis[x]=k;
}
else {
fa[y]=x;
dis[y]=k;
}
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++) fa[i]=i;
un=n;
for (int i=1;i<=m;i++){
scanf("%d%d%d",&t,&u,&v);
u=u^ans;
v=v^ans;
//printf("#%d %d\n",u,v);
if (t==0){
x=findfather(u);
y=findfather(v);
if (x!=y){
un--;
Union(x,y,i);
}
ans=un;
printf("%d\n",ans);
}
else if (t==1){
maxans=0;
fu=u;
fv=v;
lenu=0;
lenv=0;
while (fu!=fa[fu]){
fu=fa[fu];
lenu++;
}
while (fv!=fa[fv]){
fv=fa[fv];
lenv++;
}
if (fu!=fv){
ans=0;
printf("%d\n",ans);
}
else {
if (lenu>lenv){
for (int i=1;i<=lenu-lenv;i++){
maxans=max(maxans,dis[u]);
u=fa[u];
}
}
else if (lenu<lenv){
for (int i=1;i<=lenv-lenu;i++){
maxans=max(maxans,dis[v]);
v=fa[v];
}
}
while (u!=v){
maxans=max(maxans,max(dis[v],dis[u]));
u=fa[u];
v=fa[v];
}
ans=maxans;
printf("%d\n",ans);
}
}
}
return 0;
}