倍增与 LCA
核心思想:任何整数都能拆成 2 的幂之和,所以"向上跳 k 层"可以用预存的 2^j 级祖先几步跳完,O(log n)。
一、互动演示:用倍增向上跳 k 层
一条链 1→2→…→8(1 是根)。输入起点和要跳的层数 k,看 k 如何被拆成 2 的幂、一跳跳一大段。
例:从 8 跳 5 层 → 5 = 4 + 1,先跳 4 层到 4,再跳 1 层到 3。
二、倍增表与跳跃代码
// up[u][j] = u 的第 2^j 级祖先
up[u][0] = parent[u]; // 2^0 = 1 级
for (int j = 1; j < LOG; j++)
for (int u = 1; u <= n; u++)
up[u][j] = up[ up[u][j-1] ][j-1]; // 跳 2^(j-1) 两次 = 2^j
// 把 u 向上跳 k 层:按 k 的二进制位,逐位跳
for (int j = 0; j < LOG; j++)
if (k & (1 << j)) u = up[u][j];
求 LCA:先把深的一方跳到与浅的同深度,若已相同即答案;否则两点一起向上倍增,直到父节点相同。