1.定义

倍增法,顾名思义就是翻倍。它能够大大地优化时间复杂度。这个方法在很多算法中均有应用,例如求 LCA(最近公共祖先)。(大雾)

2.框架

如下图,我们想找 \(4\) 和 \(8\) 的最近公共祖先,该怎么做呢?



以人类智慧来解决,当然就是一眼看出来,他们两个的最大公共祖先是根节点,如图:



但计算机可不知道这些,所以倍增算法应运而生

他的思路是什么呢?还如图为例。

我们先让两个查询节点位于同一层上,如图



改变后为



(\(7\) 为 \(8\))

好的,然后我们让两个节点分别向上“跳”,如图



因为下面的节点没什么用,所以我在图片中删除,但在运行过程中并不是。

继续向上跳



这是我们发现,两个点出现在一起,所以 \(1\) 就是他们的最大公共祖先。

3.代码

int get_depth(int node,int father)//当前点和父亲
{
depth[node]=depth[father]+1;
fa[node][0]=father;
for(int i=1;i<=lg2[depth[node]]-1;i++)
fa[node][i]=fa[fa[node][i-1]][i-1];//node的2^i级父亲等于它的 2^(i-1)级父亲的2^(i-1)级父亲
for(int i=head[node];i;i=tree[i].next)
if(tree[i].to!=father) get_depth(tree[i].to,node);
} inline int LCA(int x,int y)
{
if(depth[x]<depth[y])
temp=x,x=y,y=temp;//确保x更深,便于处理
while(depth[x]>depth[y])
x=fa[x][lg2[depth[x]-depth[y]]-1];//跳到相同高度
if(x==y) return x;
for(int i=lg2[depth[x]]-1;i>=0;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];//注意返回的不是x,是x的父亲
}

完结散花 ⎛⎝≥⏝⏝≤⎛⎝

[学习笔记]最近公共祖先(LCA)之倍增算法的更多相关文章

  1. 学习笔记--最近公共祖先(LCA)的几种求法

    前言: 给定一个有根树,若节点\(z\)是两节点\(x,y\)所有公共祖先深度最大的那一个,则称\(z\)是\(x,y\)的最近公共祖先(\(Least Common Ancestors\)),简称\ ...

  2. [一本通学习笔记] 最近公共祖先LCA

    本节内容过于暴力没什么好说的.借着这个专题改掉写倍增的陋习,虽然写链剖代码长了点不过常数小还是很香. 10130. 「一本通 4.4 例 1」点的距离 #include <bits/stdc++ ...

  3. LCA(最近公共祖先)之倍增算法

    概述 对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,3和5的最近公共祖先是1,5和2的最近公共祖先是4 在本篇中我们先介 ...

  4. 【洛谷 p3379】模板-最近公共祖先(图论--倍增算法求LCA)

    题目:给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 解法:倍增. 1 #include<cstdio> 2 #include<cstdlib> 3 #include ...

  5. 求最近公共祖先(LCA)的各种算法

    水一发题解. 我只是想存一下树剖LCA的代码...... 以洛谷上的这个模板为例:P3379 [模板]最近公共祖先(LCA) 1.朴素LCA 就像做模拟题一样,先dfs找到基本信息:每个节点的父亲.深 ...

  6. POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)

    Tarjan算法的详细介绍,请戳: http://www.cnblogs.com/chenxiwenruo/p/3529533.html #include <iostream> #incl ...

  7. 最近公共祖先LCA Tarjan 离线算法

    [简介] 解决LCA问题的Tarjan算法利用并查集在一次DFS(深度优先遍历)中完成所有询问.换句话说,要所有询问都读入后才开始计算,所以是一种离线的算法. [原理] 先来看这样一个性质:当两个节点 ...

  8. 近期公共祖先(LCA)——离线Tarjan算法+并查集优化

    一. 离线Tarjan算法 LCA问题(lowest common ancestors):在一个有根树T中.两个节点和 e&sig=3136f1d5fcf75709d9ac882bd8cfe0 ...

  9. 求LCA最近公共祖先的在线倍增算法模板_C++

    倍增求 LCA 是在线的,而且比 ST 好写多了,理解起来比 ST 和 Tarjan 都容易,于是就自行脑补吧,代码写得容易看懂 关键理解 f[i][j] 表示 i 号节点的第 2j 个父亲,也就是往 ...

  10. POJ1470Closest Common Ancestors 最近公共祖先LCA 的 离线算法 Tarjan

    该算法的详细解释请戳: http://www.cnblogs.com/Findxiaoxun/p/3428516.html #include<cstdio> #include<alg ...

随机推荐

  1. 通过wget命令扒站仿站

    在Linux下,通过一个命令就可以把整个站相关的文件全部下载下来. wget -r -p -k -np [网址] 参数说明: -r : 递归下载 -p : 下载所有用于显示 HTML 页面的图片之类的 ...

  2. cmu15545笔记-Join算法(Join Algorithms)

    目录 Overview Nested Loop Join Naïve Block Index Sort-Merge Join Hash Join Simple Hash Join Partition ...

  3. KindleVocab 教程,Kindle导出查词记录成文本文档,Kindle导出查询单词记录导入Anki

    程序功能 因本人使用Kindle Mate导出觉得复杂,特意写了个自用的导出程序(有linux版本和win两个版本). 所以 KindleVocab 只有一个作用:导出Kindle查询过的生词和生词所 ...

  4. 【THUPC 2024 初赛】 E 转化

    [THUPC 2024 初赛] 转化 我都能做出来,那就是大水题了. 思路 首先我们要确定最大可以变色的球的数量 \(tot\). 有如下两个贪心步骤: 所有颜色使用分裂操作,并更新 \(a_i\). ...

  5. Chrome 浏览器 131 版本新特性

    Chrome 浏览器 131 版本新特性 一.Chrome 浏览器 131 版本新特性 1. 在 iOS 上使用 Google Lens 搜索 自 Chrome 126 版本以来,用户可以通过 Goo ...

  6. MPLS多协议标签交换

    多协议标签交换 MPLS(Multiprotocol Label Switching)是一种网络协议,用于在数据包交换网络中高效地进行数据路由转发.MPLS通过引入标签(Label)来对数据包进行标识 ...

  7. 高性能消息队列之nsq

    NSQ 是实时的分布式消息处理平台,其设计的目的是用来大规模地处理每天数以十亿计级别的消息. NSQ 具有分布式和去中心化拓扑结构,该结构具有无单点故障.故障容错.高可用性以及能够保证消息的可靠传递的 ...

  8. Mybatis【17】-- Mybatis自关联查询一对多查询

    注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-13-oneself-one2many,需要自取, ...

  9. GIT 使用SSH 方式提交代码

    1.需求 一般情况下,我们在提交代码的时候,使用 HTTP的方式提交代码,这种方式有一个问题,提交时需要输入账号和密码,这个就不是很安全,git 提供了 SSH的方式. 下面就实际操作一下如何使用ss ...

  10. manim边做边学--多面体

    在Manim中,对于多面体,有一系列封装好的类可以直接使用. 使用它们,可以方便快速的构建正多面体: Polyhedron:通过顶点和面的参数构建任意多面体 Tetrahedron:四面体 Octah ...