基于dfn序的O(nlogn)-O(1) lca

发布时间 2023-10-17 22:12:56作者: cqbzlzh

\(dfn\)序的长度是欧拉序的一半,常数较小,并且代码便于理解背诵。

让欧拉序求lca成为时代的眼泪。

代码部分实现思路来自cqbz_dongjie

点击查看代码
auto minlca = [&](int x, int y) {
    return (dfn[x] < dfn[y])? x : y;
};
int t = std::__lg(n) + 1;
std::vector <std::vector<int> > st(t + 1);
for (int i = 0; i <= t; i++) st[i].resize(n + 1);
for (int i = 1; i <= n; i++) st[0][dfn[i]] = fa[i];
for (int j = 1; j <= t; j++) {
    for (int i = 1; i <= n; i++) {
        st[j][i] = minlca(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
    }
}
auto lca = [&](int x, int y) {
    if (x == y) return x;
    if (dfn[x] > dfn[y]) std::swap(x, y);
    int lg = std::__lg(dfn[y] - dfn[x]);
    return minlca(st[lg][dfn[x] + 1], st[lg][dfn[y] - (1 << lg) + 1]);
};