前言

在做树上问题时,我们经常会遇到 \(LCA\)(最近公共祖先)问题。曾经的我遇到这类问题只会\(O(n)\)暴力求解,学了倍增\(LCA\),就可以\(O(logn)\)解决了。

简介

倍增\(LCA\),顾名思义,就是利用倍增来求解\(LCA\)(这真的是简介)。

主要思路

  • 我们可以用\(fa[i][j]\)来记录\(i\)的第\(2^j\)个祖先。
  • 然后,对于每一次询问\(LCA(x,y)\),我们先找到\(x\)和\(y\)最近的深度相同的祖先。
  • 接下来,我们先倍增找到最近的\(x\)和\(y\)的刚好为\(2^j\)的公共祖先。
  • 然后,我们不断减小\(j\),若当前\(fa[x][j]!=fa[y][j]\),我们就更新\(x=fa[x][j]\),\(y=fa[y][j]\),这样就可以保证修改后\(fa[x][j]=fa[y][j]\)了。
一个简短的证明

因为我们已经保证修改前的\(fa[x][j+1]=fa[y][j+1]\)了

并且,显然可得,\(fa[fa[x][j]][j]=fa[x][j+1]\),\(fa[fa[y][j]][j]=fa[y][j+1]\)(\(x\)的第\(2^j\)个祖先的第\(2^j\)个祖先即为\(x\)的第\(2^{j+1}\)个祖先,\(y\)同理)

因此,修改后的\(fa[x][j]\)和\(fa[y][j]\)就等同于修改前的\(fa[x][j+1]\)和\(fa[y][j+1]\)

得证,我们可以保证修改后\(fa[x][j]=fa[y][j]\)

  • 最后返回\(fa[x][0]\)即可。

代码

inline int LCA(int x,int y)//求x和y的最近公共祖先
{
register int i;int k;
if(dep[x]<dep[y]) swap(x,y);//比较x和y的深度,选择深度较大的节点,寻找它的与深度较小的节点深度一样的祖先
for(i=0;dep[x]^dep[y];++i) if((dep[x]^dep[y])&(1<<i)) x=fa[x][i];//如上
if(!(x^y)) return x;//如果x==y,返回x
for(k=0;fa[x][k]^fa[y][k];++k);//我们先倍增找到最近的x和y的刚好为2^j的公共祖先
for(;k>=0;--k) if(fa[x][k]^fa[y][k]) x=fa[x][k],y=fa[y][k];//不断减小j,若当前fa[x][j]!=fa[y][j],我们就更新x=fa[x][j],y=fa[y][j]
return fa[x][0];//最后返回x的父亲
}

倍增LCA的更多相关文章

  1. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  2. 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  3. Gym100685G Gadget Hackwrench(倍增LCA)

    题目大概说一棵边有方向的树,q个询问,每次询问结点u是否能走到v. 倍增LCA搞即可: 除了par[k][u]表示u结点往上走2k步到达的结点, 再加上upp[k][u]表示u结点往上走2k步经过边的 ...

  4. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  5. hdu 4674 Trip Advisor(缩点+倍增lca)

    花了一天半的时间,才把这道题ac= = 确实是道好题,好久没敲这么长的code了,尤其是最后的判定,各种销魂啊~ 题目中给出的条件最值得关注的就是:每个点最多只能在一个环内->原图是由一个个边连 ...

  6. Tsinsen A1505. 树(张闻涛) 倍增LCA,可持久化线段树,DFS序

    题目:http://www.tsinsen.com/A1505 A1505. 树(张闻涛) 时间限制:1.0s   内存限制:512.0MB    总提交次数:196   AC次数:65   平均分: ...

  7. codevs 1036 商务旅行 (倍增LCA)

    /* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...

  8. hdu 2586 How far away ?倍增LCA

    hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...

  9. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  10. 洛谷P2633 Count on a tree(主席树,倍增LCA)

    洛谷题目传送门 题目大意 就是给你一棵树,每个点都有点权,每次任意询问两点间路径上点权第k小的值(强制在线). 思路分析 第k小......又是主席树了.但这次变成树了,无法直接维护前缀和. 又是树上 ...

随机推荐

  1. 七层登录——VB.NET版

    敲完三层后,感觉还是对三层架构没有那么亲切,和小伙伴交流后,他们说多多敲几遍,就懂了,其实就是那么几条线,所以:不管会不会,先去做吧! 下面是关于七层的包图: 我的解决方案: 代码部分: U层: &l ...

  2. 软件包管理(rpm&yum)

    一.rpm包管理器 rpm是一个功能强大的包管理工具,可用于构建,安装,查询,验证,更新和卸载软件包. 用法: rpm [OPTION...] 配置文件: /var/lib/rpm/ 已安装rpm包的 ...

  3. 洛谷P4315 月下“毛景树”

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  4. iOS 限制TextField输入长度

    1 #import "MyInfoEditTableViewCell.h" @interface MyInfoEditTableViewCell()<UITextFieldD ...

  5. [题解](线段树最大连续子段和)POJ_3667_Hotel

    题意:1.求一个最靠左的长x的区间全部为0,并修改为1,输出这个区间的左端点 2.修改一个区间为0 实际上是维护最大连续子段和,原来也写过 大概需要维护一个左/右最大子段和,当前这段最大子段长,再维护 ...

  6. jmeter小问题解决方案合集

    问题1.在http请求,post的body中输入中文,显示乱码,怎么解决? 在jmeter的bin目录下,找到这个文件jmeter.properties,把jsyntaxtextarea.font.f ...

  7. 有效使用Mock编写java单元测试

    Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构.然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编 ...

  8. 在startup中遍历程序集

    在aspnetcore中是可以使用AppDomain的,如:在ConfigureServices中,可以使用以下代码获取项目引用的所有dll, var assemblies = AppDomain.C ...

  9. tomcat的webapps下放置多个项目时会出现很多exception

    今天干了一件比较逗比的事,在tomcat的项目目录wepapps下又新建了一个文件夹backup,然后在backup下放置了之前项目的war包...然后启动tomcat的时候各种exception 大 ...

  10. 2016年5月8日 GDCPC省赛总结

    入坑ACM半年多了,从开始的a+b,到现在,懵懵懂懂地去参加了省赛......成绩虽然不是特别好,但希望自己能坚持下去吧,肯付出不一定有收获,但是不付出就一定没有收获啦!而且我也挺喜欢ACM的,最起码 ...