【模板】最近公共祖先LCA——倍增
题目来自洛谷P3379 【模板】最近公共祖先(LCA)
【模板】最近公共祖先(LCA)
题目描述
如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。
输入格式
第一行包含三个正整数 ,分别表示树的结点个数、询问的个数和树根结点的序号。
接下来 行每行包含两个正整数 ,表示 结点和 结点之间有一条直接连接的边(数据保证可以构成树)。
接下来 行每行包含两个正整数 ,表示询问 结点和 结点的最近公共祖先。
输出格式
输出包含 行,每行包含一个正整数,依次为每一个询问的结果。
样例 #1
样例输入 #1
样例输出 #1
提示
对于 的数据,,。
对于 的数据,,。
对于 的数据,,,不保证 。
样例说明:
该树结构如下:
第一次询问: 的最近公共祖先,故为 。
第二次询问: 的最近公共祖先,故为 。
第三次询问: 的最近公共祖先,故为 。
第四次询问: 的最近公共祖先,故为 。
第五次询问: 的最近公共祖先,故为 。
故输出依次为 。
2021/10/4 数据更新 @fstqwq:应要求加了两组数据卡掉了暴力跳。
最近公共祖先——树上倍增
预处理(倍增)
表示从结点出发,向上跳步所抵达的节点编号;
求解方式:
, 向上跳步后再跳步就可以跳到的位置,所以,
表示结点的深度;
哨兵: , 表示向上跳步跳出根结点的范围。
实现方式:
查询
查询分两步走:
()先将两个点跳到同一层
该步骤可以使用二进制拼凑的方式来实现。假设,则两者之间的差距为,由于是按照的整数幂向上跳,所以可以通过取的二进制表示中所在的位对应的权值进行跳跃即可将跳到与同一层。
在实现过程中,可以从大到小枚举指数,当时,, 这样当跳到与同一层时就会停止跳跃。
如果在这一步后, 则直接返回.
()两个点同时向上跳,直到跳到最近公共祖先的下一层
为什么是下一层?因为如果直接判断是否跳到同一个节点,无法判断是否为最近的公共祖先,而有可能只是一个公共祖先。
判断条件: 从大到小枚举指数, , 。
当时,证明此时已经跳到了最近公共祖先的下一层, 此时或就是答案。
__EOF__

本文链接:https://www.cnblogs.com/yjx-7355608/p/17694445.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】