倍增lca
```cpp
#include<bits/stdc++.h>
using namespace std;
const int M=5e5+100;
struct st{
int nxt,to;
}edge[M<<1];
int head[M],num;
void add(int x,int y){
edge[++num].to=y;
edge[num].nxt=head[x];
head[x]=num;
}
int n,m,s,f[20][M],dep[M];
//f[i][x]表示x的上面2^i层是多少
void dfs(int u,int father){
dep[u]=dep[father]+1;//深度
f[0][u]=father;
for(int i=1;i<=18;i++)//从小到大
f[i][u]=f[i-1][f[i-1][u]];//递推,u的上方2^(i-1)层的再上面2^(i-1)层是2^i层
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==father)continue;
dfs(v,u);
}
}
int lca(int x,int y){
if(dep[x]>dep[y])swap(x,y);//保证y在下面
for(int i=18;i>=0;i--){
if(dep[f[i][y]]>=dep[x])y=f[i][y];//向上跳在x下面
if(x==y)return x;
}
for(int i=18;i>=0;i--)
if(f[i][x]!=f[i][y]){
x=f[i][x];
y=f[i][y];
}//不一样就向上跳,实际是二进制的想法
return f[0][x];//最后肯定在下一层
}
int main(){
scanf("%d%d%d",&n,&m,&s);
for(int i=1,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(s,0);
while(m--){
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",lca(a,b));
}
return 0;
}