10分球住
查看原帖
10分球住
227728
冰糖鸽子TJ鸽子协会楼主2020/11/4 19:56

RT,只AC点1,其余点WA

不要说下载数据,第二个点直接极限数据我下载个寂寞

// Problem: P3379 【模板】最近公共祖先(LCA)
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3379
// Memory Limit: 500 MB
// Time Limit: 1500 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
int n,m,k,u,v,f[500010][30],a[500010],vis[500010];
vector<int>road[500010];
void dfs(int x,int now,int y)
{
	if(vis[x]){return;}
	a[x]=now;f[x][0]=y;
	vis[x]=1;
	for(int i=1;i<=log2(now);i++)
	{
		f[x][i]=f[f[x][i-1]][i-1];//副体
	}
	for(int i=0;i<road[x].size();i++)
	{
		dfs(road[x][i],now+1,x);
	}
	return;
}
void find_ans(int x,int y)//主体
{
	int lx=a[x],ly=a[y];
	int fc=abs(lx-ly);
	if(!lx){printf("%d \n",x);return;}
	if(!ly){printf("%d \n",y);return;}
	//Step 1:跳到同样高度
	if(fc)
	{
		if(lx<ly)
		{
			swap(x,y);
			swap(lx,ly);
		}
		for(int i=pow(2,int(log2(fc)));i>0;i/=2)
		{
			if(fc-i<0)
			{
				continue;
			}
			fc-=i;
			x=f[x][int(log2(i))];
		}
	}
	//Step 2:跳到LCA
	for(int i=pow(2,int(log2(a[x])));i>0;i/=2)
	{
		 if(f[x][int(log2(i))]==f[y][int(log2(i))])
		 {
		 	continue;
		 }
		 x=f[x][int(log2(i))],y=f[y][int(log2(i))];
	}
	printf("%d \n",f[x][0]);
}
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		road[u].push_back(v);
		road[v].push_back(u);
	}
	dfs(k,0,-1);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&u,&v);
		find_ans(u,v);
	}
	return 0;
}
2020/11/4 19:56
加载中...