模板: 树链剖分求LCA
void dfs1(int x)
{
size[x]=1;
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(dep[y]) continue;
dep[y]=dep[x]+1; fa[y]=x;
dfs1(y);
size[x]+=size[y];
if(size[son[x]]<size[y]) son[x]=y;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(y==son[x]||y==fa[x]) continue;
dfs2(y,y);
}
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];//topx与topy
return dep[x]<dep[y]?x:y;
}
int main()
{
n=read(); m=read(); s=read();
for(int i=1;i<n;i++) add(read(),read());
dep[s]=1; fa[s]=0;
dfs1(s); dfs2(s,s);
while(m--)
printf("%d\n",LCA(read(),read()) );
return 0;
}
注意: 树链剖分比较的是\(dep[top[x]]\ \& \ dep[top[y]]\)

浙公网安备 33010602011771号