求 LCA
一、倍增
预处理
二、tarjan
狗都不用。询问离线。总共
三、树剖
预处理
int Lca(int x, int y) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
x = fa[top[x]];
}
return dep[x] < dep[y] ? x : y;
}
四、欧拉序列
注意!!!不是即这棵树的括号序列。
而是:递归
每个点 1 次,每条边 1 次,所以欧拉序列的长度为
定义【欧拉序】表示一个点在欧拉序列中第一次出现的位置
欧拉序有以下两条性质:
-
任意两点简单路径上所有节点均在它们的欧拉序之间出现。
-
任意两点欧拉序之间不会出现它们 LCA 子树外的点。
然后 st 表查询区间里面深度最小值对应的点即可。预处理线性对数,查询常数。
void dfs(int x, int y) {
dep[x] = dep[y] + 1; fa[x] = y, dis[x] = dis[y] + (x <= n);
f[dfn[x] = ++tcnt][0] = x;
for(int to : E[x]) {
if(to == y) continue ;
dfs(to, x);
f[++tcnt][0] = x;
}
}
int get(int x, int y) { return dep[x] < dep[y] ? x : y; }
int Lca(int l, int r) {
if(l == r) return l;
l = dfn[l], r = dfn[r];
if(l > r) swap(l, r);
int k = __lg(r - l + 1);
return get(f[l][k], f[r - (1 << k) + 1][k]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】