• LCA 的若干种求法


    LCA 的若干种求法

    对于有根树来说,LCA 指两点的最近公共祖先。求法较多,下面选取一些有特色的求法来讲解。

    树链剖分法

    特点: O ( n ) O(n) O(n) 预处理,单次 O ( log ⁡ n ) O(\log n) O(logn)

    首先对树进行轻重链剖分预处理。

    在求两个点 u , v u,v u,v 的 LCA 时,分为以下两种情况:

    • u , v u,v u,v 在同一条重链上,则两者为祖孙关系,返回深度小的点;
    • u , v u,v u,v 不在同一条重链上,则可以把更深的那条重链跳过去,LCA 不变。

    由于重链数量为 O ( log ⁡ n ) O(\log n) O(logn),所以单次复杂度为 O ( log ⁡ n ) O(\log n) O(logn)

    提交记录

    倍增法

    特点: O ( n log ⁡ n ) O(n\log n) O(nlogn) 预处理,单次 O ( log ⁡ n ) O(\log n) O(logn),常数大,空间大,所以被上者吊打。

    改进自逐步上移法。大致分为两个过程:

    • 先让深度大的点上移,直到两个深度相等。
    • 再让两个点一直向上移动相同步,直到到同一个点。

    这两过程均可使用倍增加速。

    提交记录

    dfs 序+RMQ 法

    原来是打算用欧拉序+RMQ 法的,但好像改用 dfs 序也挺好的,常数更小一点。

    特点: O ( n log ⁡ n ) O(n\log n) O(nlogn) 预处理,单次 O ( 1 ) O(1) O(1)

    首先我们对整棵树进行一次 dfs 得到 dfs 序。假如我们求的是 u , v u,v u,v 的 LCA (其中 d f n u < d f n v dfn_udfnu<dfnv)。无非两种情况:

    1. u u u v v v 在其 LCA 的两棵子树内。
      这种情况下, u , v u,v u,v 的 LCA 的时间戳并不在 [ d f n u , d f n v ] [dfn_u,dfn_v] [dfnu,dfnv] 中。但是, v v v 所在子树离 LCA 最近的节点一定在 [ d f n u , d f n v ] [dfn_u,dfn_v] [dfnu,dfnv] 中,且一定为深度最小点。我们只需要求出 [ d f n u , d f n v ] [dfn_u,dfn_v] [dfnu,dfnv] 中深度最小点,再取其父亲,就是 LCA 了。
    2. u u u v v v 的祖先。这个时候 LCA 就是 u u u

    我们综合 1 2,只要取出 [ d f n u + 1 , d f n v ] [dfn_u+1,dfn_v] [dfnu+1,dfnv] 中的深度最小点,再取其父亲即可。这个可以用 st 表处理。

    提交记录

    Tarjan 法的

    还不会

  • 相关阅读:
    浅谈基于LoRa技术下智能建筑能耗管理系统的分析与设计
    matplotlib做时钟
    SAP 灵活工作流邮件通知
    前端关于对象中套用对象传参的小问题
    Java设计模式之六大设计原则
    【蓝桥杯Web】第十三届蓝桥杯(Web 应用开发)第一次线上模拟赛
    【OJ比赛日历】快周末了,不来一场比赛吗? #10.29-11.04 #7场
    ModStartCMS v5.1.0 数据采集接口,登录自动注册
    springcloud中feign组件使用
    找准方向选CRM客户管理系统!2023年排行榜推荐
  • 原文地址:https://blog.csdn.net/qq_41996523/article/details/126014343