分析:
用并查集维护一个边权为时间的最小生成树,为了减小树高需要按秩合并。
其实想要达到O(nlogn)复杂度树剖+ST表或LCT都行......
代码:
贴个别人的博客,我实在是不想写了:https://blog.csdn.net/just_sort/article/details/52253481
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 500010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
int f[MAXN],h[MAXN],v[MAXN],dep[MAXN];
int la;
int T;
int n,m;
int fa(int x){
return f[x]==x?x:fa(f[x]);
}
void pre(int x){
if(f[x]==x){
return ;
}
pre(f[x]);
dep[x]=dep[f[x]]+1;
}
int ask(int x,int y){
pre(x);
pre(y);
if(dep[x]<dep[y]){
swap(x,y);
}
int re=0;
while(dep[x]>dep[y]&&x!=y){
re=max(re,v[x]);
x=f[x];
}
while(x!=y){
re=max(re,max(v[x],v[y]));
x=f[x];
y=f[y];
}
return re;
}
int main(){
int i,o,x,y;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
f[i]=i;
}
while(m--){
scanf("%d%d%d",&o,&x,&y);
x^=la;
y^=la;
if(o==0){
int fx=fa(x),fy=fa(y);
T++;
if(fx!=fy){
if(h[fx]<=h[fy]){
f[fx]=fy;
v[fx]=T;
if(h[fx]==h[fy]){
h[fy]++;
}
}else{
f[fy]=fx;
v[fy]=T;
}
}
}
if(o==1){
int fx=fa(x),fy=fa(y);
if(fx!=fy){
printf("%d\n",la=0);
}else{
printf("%d\n",la=ask(x,y));
}
}
}
return 0;
}
/*
*/