题目
luogu3379
ST表求LCA
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 1000005
using namespace std;
int n,m,root,f[N][25];
int num,a[N],b[N],nt[N],p[N];
void add(int x,int y)
{
a[num++]=x;b[num]=y;
nt[num]=p[x];p[x]=num;
}
int t,deep[N],dfn[N],la[N];bool flag[N];
void dfs(int k)
{
flag[k]=1;
for(int e=p[k];e;e=nt[e])
{
int kk=b[e];
if(flag[kk]) continue;//除去父节点
deep[kk]=deep[k]+1;
dfn[++t]=k;
dfs(kk);
}
dfn[++t]=k;la[k]=t;//la[i]记录i最后出现的dfs序
}
int Min(int x,int y)
{
if(deep[x]<deep[y]) return x;
return y;
}
void pre()
{
for(int i=1;i<=t;i++) f[i][0]=dfn[i];
for(int j=1;j<=23;j++)
for(int i=1;i+(1<<j)-1<=t;i++)
f[i][j]=Min(f[i][j-1],f[i+(1<<j-1)][j-1]);
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
n=read();m=read();root=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
add(x,y);add(y,x);
}
dfs(root);
pre();
for(int i=1;i<=m;i++)
{
int x=read(),y=read();
x=la[x];y=la[y];
if(x>y) swap(x,y);
int k=log2(y-x+1);
printf("%d\n",Min(f[x][k],f[y-(1<<k)+1][k]));
}
return 0;
}