LCA
倍增法求最近公共祖先
首先对于每个结点先进行dfs预处理它的深度,再记录下它们往父亲方向走2的0次,1次...k次步所到达的结点。在这里2的k次大于整棵树的最大深度。
预处理完后,需要查询两个点u,v的LCA时,先将u,v中深度较大的利用预处理的数组走到和另一个结点相同深度,操作次数不会超过log2|depth(u)-depth(v)|
接下来从k开始往下枚举,如果u和v往上走2的i次后不同那么它们一起往上走那么多步
预处理 O(nlogn)查询O(logn)
不仅如此我们可以动态地给树增加一些叶子结点,在预处理时还可以记录下这段路径权值最大值,最小值或权值和之类的信息。
Luogu P3379 https://www.luogu.com.cn/problem/P3379
#include
#include
#include<string>
#include
#include
#include<set>
#include
邻接表版本
#include
#include
#include<string>
#include
#include
#include<set>
#include
POJ 1330 (邻接表存储)
#include
#include
#include<string>
#include
#include
#include<set>
#include
CodeForces - 697C Lorenzo Von Matterhorn
不需要求出LCA 数的移动(二叉树编号)
#include
#include
倍增应用

From OI wiki
#include
#include
#include<string>
#include
#include
#include<set>
#include