어떤 문제를 푸는가
루트가 있는 트리에서 두 정점 \(u, v\)의 최소 공통 조상(LCA) — 둘을 모두
자손으로 갖는 조상 중 가장 깊은 정점 — 을 빠르게 구합니다. 트리에서 두 정점
사이의 경로, 거리, 경로 위 질의 등의 핵심 부품입니다.
트리에서 \(u, v\) 사이의 유일한 경로는 항상 \(u \to \text{LCA} \to v\) 형태이므로,
LCA만 알면 경로 길이는
$$ \text{dist}(u, v) = \text{depth}(u) + \text{depth}(v) - 2\cdot\text{depth}(\text{LCA}) $$
로 즉시 구합니다.
단순 방법과 그 한계
두 정점을 같은 깊이로 맞춘 뒤 함께 한 칸씩 올라가면 LCA를 찾을 수 있지만,
한 번에 \(O(\text{높이})\)가 들어 트리가 길면 질의당 \(O(N)\)입니다. 질의가 많으면
느립니다.
희소 배열 (Binary Lifting)
각 정점의 \(2^k\)번째 조상 을 미리 표로 저장합니다.
$$ up[k][v] = v \text{의 } 2^k \text{번째 조상} $$
점화식은
$$ up[k][v] = up[k-1]\bigl(up[k-1][v]\bigr) $$
"\(2^k\)칸 위 = \(2^{k-1}\)칸 두 번"이라는 단순한 관계입니다. \(up[0][v]\)는 직접
부모입니다. \(k\)는 \(0\)부터 \(\lceil \log_2 N \rceil\)까지 둡니다.
질의 — 두 단계
- 깊이 맞추기 — 더 깊은 정점을 \(2^k\) 점프들로 끌어올려 두 정점 깊이를
같게 한다. 깊이 차를 이진수로 보고 켜진 비트만큼 점프. - 함께 올라가기 — 두 정점이 달라지는 가장 큰 점프 를 큰 \(k\)부터 시도해
함께 올린다. 더 못 올라가는 지점 바로 위가 LCA(즉up[0]).
큰 점프부터 시도하는 이유: LCA 바로 아래까지 최대한 올라가되 LCA를 넘지 않기
위해서입니다.
복잡도
| 단계 | 시간 |
|---|---|
| 전처리 (표 구축) | \(O(N \log N)\) |
| 질의당 | \(O(\log N)\) |
| 공간 | \(O(N \log N)\) |
전처리 한 번에 표를 만들어 두면 이후 모든 질의가 \(O(\log N)\)입니다.
다른 접근들
- 오일러 투어 + 희소 테이블(RMQ) — 전처리 \(O(N \log N)\), 질의 \(O(1)\).
- 오프라인 타잔 LCA — 유니온 파인드로 \(O((N+Q)\alpha)\).
대부분의 문제에선 구현이 깔끔한 희소 배열이 표준입니다. 다음 강의에서 구현과
응용을 봅니다.