LCA模板
倍增
#include<bits/stdc++.h>
using namespace std;
//#define int long long
struct Tree {
int nxt,to;
} edge[500005*4];
int cnt,head[500005*4];
int n,m,s,fa[500005][25],dep[500005],lg[500005];
char *p1,*p2,buf[100000];
#define nc() (p1==p2 && (p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int read() {
int x=0,f=1;
char ch=nc();
while(ch<48||ch>57) {
if(ch=='-')
f=-1;
ch=nc();
}
while(ch>=48&&ch<=57)
x=x*10+ch-48,ch=nc();
return x*f;
}
void write(int x) {
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
return;
}
void add(int u,int v) {
cnt++;
edge[cnt].nxt=head[u];
edge[cnt].to=v;
head[u]=cnt;
}
void dfs(int u,int fat) { //fa[i][j]:节点i的2^j级祖先
fa[u][0]=fat,dep[u]=dep[fat]+1;
for(int i=1; i<=lg[dep[u]]; i++)
fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i=head[u]; i; i=edge[i].nxt) {
int v=edge[i].to;
if(v==fat)continue;
dfs(v,u);
}
}
int LCA(int x,int y) {
if(dep[x]<dep[y])swap(x,y);
while(dep[x]>dep[y])
x=fa[x][lg[dep[x]-dep[y]]-1];
if(x==y)return x;
for(int k=lg[dep[x]]-1; k>=0; k--)
if(fa[x][k]!=fa[y][k])
x=fa[x][k],y=fa[y][k];
return fa[x][0];
}
signed main() {
n=read(),m=read(),s=read();
for(int i=1; i<n; i++) {
int x,y;
x=read(),y=read();
add(x,y);
add(y,x);
}
for(int i=1; i<=n; i++)
lg[i]=lg[i-1]+(1<<lg[i-1]==i);
dfs(s,0);
for(int i=1; i<=m; i++) {
int x=read(),y=read();
write(LCA(x,y));
putchar('\n');
}
return 0;
}
注意 lg[i]:log2(i)+1
一定要用scanf 或者快读 用ios::sync_with_stdio(false)会被卡T
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号