题目链接:https://www.luogu.org/problem/P3379
学习链接:https://blog.youkuaiyun.com/Diogenes_/article/details/81412316
预处理时间复杂度O(NlogN)
查询时间复杂度O(1)
#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define pb push_back
using namespace std;
const int N = 5e5+1; //点数
int st[N],cnt,euler[N*2],deep[N];
vector<int> nxt[N];
void dfs(int u,int f) {
deep[u] = deep[f]+1;
euler[++cnt] = u;
st[u] = cnt;
for(auto v:nxt[u]) {
if(v==f) continue;
dfs(v,u);
euler[++cnt] = u;
}
}
//------------------------------------------------------
int dp[2*N][25];
int cal(int x,int y) {
if(deep[x]<deep[y]) return x;
else return y;
}
void RMQ(int n){
for(int i = 1; i <= n; i++) dp[i][0] = euler[i];
for(int i = 1; i < 25; i++)
for(int j = 1; j + (1 << i) - 1 <= n; j++)
dp[j][i] = cal(dp[j][i-1],dp[(j+(1<<(i-1)))][i-1]);
}
int q_min(int x,int y){
int k = (int)((log(y - x + 1) * 1.0) / log(2.0));
return cal(dp[x][k],dp[y - (1<<k) + 1][k]);
}
//-------------------------------------------------------
int q_lca(int u,int v) {
if(st[u]>st[v]) swap(u,v);
return q_min(st[u],st[v]);
}
//-------------------------------------------------------
int n,m,root;
int main() {
scanf("%d%d%d",&n,&m,&root);
int u,v;
rep(i, 1, n-1) {
scanf("%d%d",&u,&v);
nxt[u].pb(v);
nxt[v].pb(u);
}
dfs(root,0);
RMQ(2*n);
rep(i, 1, m) {
scanf("%d%d",&u,&v);
printf("%d\n",q_lca(u,v));
}
return 0;
}