P3379 最近公共祖先模板
顾名思义 就是求两个点的公共祖先
暴力做法就是先维护每个点的父亲 然后枚举
但显然这样的做法查询复杂度是O(n)的 就TLE了(
所以需要用倍增优化:
用f[i][j]表示第i个点 向上跳
显然 有f[i][0] = fa[i] :
然后是递推式 不难看出f[i][j]可以看作是i先跳
至此 预处理完成 复杂度为O(nlogn)
那么如何查找 x 与 y 的最近公共祖先呢?
首先我们先将较低的那个跳到与另一个深度相同:
注意跳完后可能发生以下情况:
所以当 x 跳完与 y 重合 我们就直接输出:
然后 x 与 y 就能一起往上跳了
我们把 j 从大到小枚举 若 f[x][j] == f[y][j] 就说明跳过头了 :
所以 x 与 y 往上跳的条件即为 f[x][j] != f[y][j] :
当然 最后 x 与 y 会停在离最近公共祖先差一格的位置(因为再往上一格 f[x][j] 就等于 f[y][j] 没法跳)
所以此时输出 f[x][0] ( f[y][0] 一样的 写啥看心情 甚至我感觉其实写 fa[x] 都行 )
查询的复杂度为O(logn)
完整代码如下:
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】博客园携手 AI 驱动开发工具商 Chat2DB 推出联合终身会员
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个适用于 .NET 的开源整洁架构项目模板
· API 风格选对了,文档写好了,项目就成功了一半!
· 【开源】C#上位机必备高效数据转换助手
· .NET 9.0 使用 Vulkan API 编写跨平台图形应用
· MyBatis中的 10 个宝藏技巧!