• 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
    ",ans);
    			if(type)lastans=ans;
    		}
    	}
    }
    
    
  • 相关阅读:
    如何优雅地用MATLAB生成C语言从1打印到100再打印到1
    CentOS启动报错Failed to mount /sysroot解决方法
    JVM性能监控与调优篇
    Redis 配置文件详解(翻译版,不全,有时间继续更新)
    odoo五种Action详解
    odoo环境变量env(Environment)
    odooenvmodel
    odoo常用的函数
    HashMap简单实现
    xshell6提示“要继续使用此程序,您必须应用最新的更新或使用新版本”解决办法
  • 原文地址:https://www.cnblogs.com/naruto-mzx/p/13033606.html
Copyright © 2020-2023  润新知