LCA倍增标程
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,s,x,y;
struct {int to,next;}a[1000010];
int head[500010],deep[500010],zx[500010][20],tot;
void build(int x,int y)
{
a[++tot].to=y;
a[tot].next=head[x];
head[x]=tot;
}
void dfs(int now,int father)
{
for(int i=head[now];i;i=a[i].next)
{
if(a[i].to!=father)
{
deep[a[i].to]=deep[now]+1;
dfs(a[i].to,now);
zx[a[i].to][0]=now;
}
}
}
void ready()
{
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
zx[i][j]=zx[zx[i][j-1]][j-1];
}
void swap(int &f,int &g)
{
int p=f;
f=g;
g=p;
}
int lca(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
int maxlog=log(n)/log(2);
for(int i=maxlog;i>=0;i--)
if(deep[x]-(1<<i)>=deep[y])
x=zx[x][i];
if(x==y) return x;
for(int i=maxlog;i>=0;i--)
if(zx[x][i]!=zx[y][i])
{
x=zx[x][i];
y=zx[y][i];
}
return zx[x][0];
}
int main()
{
cin>>n>>m>>s;
for(int i=1;i<=n-1;i++)
{
scanf("%d%d",&x,&y);
build(x,y);
build(y,x);
}
dfs(s,s);
ready();
zx[s][0]=s;
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",lca(a,b));
}
}