LCA的各类解法(二)——树链剖分求LCA

本文介绍了一种使用树链剖分求最近公共祖先(LCA)的方法,该方法相较于传统倍增LCA更快,拥有O(n)预处理时间和O(log(n))查询时间。文章详细解释了算法流程并提供了实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文参考自: 原文地址

树链剖分求LCA其实就是树剖的一个应用.

不会树剖的点这里.

树剖求LCA的速度还很快,O(n)预处理,O(log(n))查询,相较于倍增LCA更快,而且求LCA那部分更好写,但是dfs部分比较难写.

整个算法流程就是先两个dfs预处理,然后一个判断u与v是否在同一条重链,不在就往上跳,最后得到LCA.

至于为什么查询是O(log(n))的,因为我们可以证明重链只有log(n)条,所以是O(n)的.

代码如下:

void dfs2(int k,int start){
  nod[k].top=start;
  if (nod[k].son) dfs2(nod[k].son,start);
  for (int i=lin[k];i;i=e[i].next)
    if (e[i].y^nod[k].son&&e[i].y^nod[k].dad) dfs2(e[i].y,e[i].y);
}
int LCA(int u,int v){
  while (nod[u].top^nod[v].top)
    if (nod[nod[u].top].deep>nod[nod[v].top].deep) u=nod[nod[u].top].dad;
    else v=nod[nod[v].top].dad;
  return nod[u].deep<nod[v].deep?u:v;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值