Loj #6038. 「雅礼集训 2017 Day5」远行 |LCA启发式合并

题面


#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long long
const int N=3e5+5;
inline int read(){
	int x=0; char c=getchar();
	while(c<'0'||c>'9')c=getchar();
	while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48); c=getchar();}
	return x;
}
int nxt[N<<1],head[N],go[N<<1],tot;
inline void add(int u,int v){
	nxt[++tot]=head[u],head[u]=tot,go[tot]=v;
	nxt[++tot]=head[v],head[v]=tot,go[tot]=u;
}
int type,n,q,dis[N],fa[N],siz[N],f[N][21],dep[N],a[N][2];
int get(int x){
	return (x==fa[x])?x:fa[x]=get(fa[x]);	
}
void dfs(int u,int fa){
	f[u][0]=fa,dep[u]=dep[fa]+1;
	for(int i=1;i<=20;i++)f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i;i=nxt[i]){
		int v=go[i];
		if(v==fa)continue;
		dfs(v,u);	
	}
}
inline int LCA(int x,int y){
	if(dep[x]<dep[y])swap(x,y);
	for(int i=20;i>=0;i--)if(dep[f[x][i]]>=dep[y])x=f[x][i];
	if(x==y)return x;
	for(int i=20;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
	return f[x][0];
}
inline int Dis(int x,int y){
	return dep[x]+dep[y]-2*dep[LCA(x,y)];
}
int lastans=0;
signed main(){
	type=read(),n=read(),q=read();
	for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1,a[i][0]=a[i][1]=i;
	for(int i=1;i<=n;i++)
	for(int j=0;j<=20;j++)f[i][j]=i;
	int t,u,v;
	while(q--){
		t=read();
		if(t==1){
			u=read()^lastans,v=read()^lastans;
			add(u,v);
			int x=get(u),y=get(v);
			if(siz[x]>siz[y])swap(x,y),swap(u,v);
			fa[x]=y; siz[y]+=siz[x];
			dfs(u,v);
			int op1=0,op2=0,Max=-1;
			for(int i=0;i<2;i++)for(int j=0;j<2;j++)
			if(Max<Dis(a[x][i],a[y][j]))
			Max=Dis(a[x][i],a[y][j]),op1=a[x][i],op2=a[y][j];
			if(Max<Dis(a[x][0],a[x][1]))
			Max=Dis(a[x][0],a[x][1]),op1=a[x][0],op2=a[x][1];
			if(Max<Dis(a[y][0],a[y][1]))
			Max=Dis(a[y][0],a[y][1]),op1=a[y][0],op2=a[y][1];
			a[y][0]=op1,a[y][1]=op2;
		}else{
			u=read()^lastans;	
			int x=get(u);
			int ans=max(Dis(a[x][0],u),Dis(a[x][1],u));
			printf("%d\n",ans);
			if(type)lastans=ans;
		}
	}
}

posted @ 2020-06-02 20:45  白木偶君  阅读(168)  评论(0编辑  收藏  举报