倍增法 Subtask#1 0分求调
查看原帖
倍增法 Subtask#1 0分求调
685183
LightSpot楼主2024/4/4 14:58
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 500050 , lg2MAXN = 20;
vector <int> a[MAXN];
int n , m , s , maxi[MAXN]; 
int deep[MAXN] , fa[MAXN][lg2MAXN];
void init(int p , int fno)
{
	fa[p][0] = fno;
	deep[p] = deep[fno] + 1;
	for(int i = 1 ; (1 << i) <= deep[p] ; i++) maxi[p] = i , fa[p][i] = fa[fa[p][i - 1]][i - 1];
	int sz = a[p].size();
	for(int i = 0 ; i < sz ; i++)
	{
		if(a[p][i] == fno) continue;
		init(a[p][i] , p);
	}
	return;
}
int lca(int p1 , int p2)
{
	if(deep[p1] != deep[p2])
	{
		while(deep[p1] < deep[p2]) p2 = fa[p2][0];
		while(deep[p1] > deep[p2]) p1 = fa[p1][0];
	}
	if(p1 == p2) return p1;
	for(int i = maxi[p1] ; i >= 0 ; i--)
	{
		if(fa[p1][i] == 0 || fa[p1][i] == fa[p2][i]) continue;
		p1 = fa[p1][i] , p2 = fa[p2][i];
	}
	return fa[p1][0];
}
int main()
{
	scanf("%d%d%d" , &n , &m , &s);
	for(int i = 1 ; i <= n - 1 ; i++)
	{
		int tmp1 , tmp2;
		scanf("%d%d" , &tmp1 , &tmp2);
		a[tmp1].push_back(tmp2);
		a[tmp2].push_back(tmp1);
	}
	init(s , 0);
	for(int i = 1 ; i <= m ; i++)
	{
		int tmp1 , tmp2;
		scanf("%d%d" , &tmp1 , &tmp2);
		int ans = lca(tmp1 , tmp2);
		printf("%d\n" , ans);
	}
	return 0;
}


2024/4/4 14:58
加载中...