Skip to Content
Team NoteAlgorithmLCAO1

LCAO1

struct LCA_O1 { int N, LOG = 0, dfsn = 0; vvi edges; vi level, in, e, lg2, pw2; vector<vector<pi>> sparse; LCA_O1(int N) : N(N), level(N), in(N, -1), e(N * 2 - 1), edges(N), lg2(N * 2, -1) { for (; (1 << LOG) <= N; LOG++); LOG++; sparse.resize(N * 2 - 1, vector<pi>(LOG)); pw2.resize(LOG, 1); } void add_edge(int i, int j) { edges[i].pb(j); } void dfs(int cur, int l) { level[cur] = l; e[dfsn] = cur; in[cur] = dfsn++; for (int to: edges[cur]) { if (in[to] == -1) { dfs(to, l + 1); e[dfsn++] = cur; } } } void build(int root = 0) { for (int i = 1, k = 0; i < N * 2; i <<= 1, k++) lg2[i] = k; for (int i = 2; i < N * 2; i++) if (lg2[i] == -1)lg2[i] = lg2[i - 1]; for (int i = 1; i < LOG; i++) pw2[i] = pw2[i - 1] << 1; dfs(root, 0); for (int i = 0; i < N * 2 - 1; i++) sparse[i][0] = {level[e[i]], e[i]}; for (int k = 1; k < LOG; k++) { for (int i = 0; i + pw2[k - 1] < N * 2 - 1; i++) { int j = i + pw2[k - 1]; sparse[i][k] = min(sparse[i][k - 1], sparse[j][k - 1]); } } } int find(int a, int b) { int l = min(in[a], in[b]), r = max(in[a], in[b]), k = lg2[r - l + 1]; r -= pw2[k] - 1; return min(sparse[l][k], sparse[r][k]).se; } int dist(int a, int b) { int l = find(a, b); return level[a] + level[b] - level[l] * 2; } };
Last updated on