On this page
article
LCA com HLD
Sobre
Assume que um vertice eh ancestral dele mesmo, ou seja,
se a eh ancestral de b, lca(a, b) = a
Para buildar pasta chamar build(root)
anc(a, b) responde se ‘a’ eh ancestral de ‘b’
Complexidades:
build - O(n)
lca - O(log(n))
anc - O(1)
Link original: lcaComHld.cpp
Código
vector<int> g[MAX];
int pos[MAX], h[MAX], sz[MAX];
int pai[MAX], t;
void build(int k, int p = -1, int f = 1) {
pos[k] = t++; sz[k] = 1;
for (int& i : g[k]) if (i != p) {
pai[i] = k;
h[i] = (i == g[k][0] ? h[k] : i);
build(i, k, f); sz[k] += sz[i];
if (sz[i] > sz[g[k][0]] or g[k][0] == p) swap(i, g[k][0]);
}
if (p*f == -1) t = 0, h[k] = k, build(k, -1, 0);
}
int lca(int a, int b) {
if (pos[a] < pos[b]) swap(a, b);
return h[a] == h[b] ? b : lca(pai[h[a]], b);
}
bool anc(int a, int b) {
return pos[a] <= pos[b] and pos[b] <= pos[a]+sz[a]-1;
}