본문으로 건너뛰기
김신건의 로그

Binary Lifting: 2의 지수 doubling

· 수정 · 📖 약 1분 · 84자/단어 #algorithm #math #tree #lca
Binary Lifting, 이진 상승, sparse ancestor

정의

트리에서 정점의 2^k 조상 을 O(N log N) 전처리 후 O(log N) 쿼리로 답하는 기법. LCA, k-th ancestor 등에 사용.

전처리

const int LOG = 20;
vector<vector<int>> up(n, vector<int>(LOG));

void dfs(int u, int p) {
    up[u][0] = p;
    for (int k = 1; k < LOG; k++)
        up[u][k] = up[u][k-1] < 0 ? -1 : up[up[u][k-1]][k-1];
    for (int v : adj[u]) if (v != p) {
        depth[v] = depth[u] + 1;
        dfs(v, u);
    }
}

LCA 쿼리

int lca(int u, int v) {
    if (depth[u] < depth[v]) swap(u, v);
    int diff = depth[u] - depth[v];
    for (int k = 0; k < LOG; k++)
        if (diff & (1 << k)) u = up[u][k];
    if (u == v) return u;
    for (int k = LOG - 1; k >= 0; k--)
        if (up[u][k] != up[v][k]) { u = up[u][k]; v = up[v][k]; }
    return up[u][0];
}

O(log N) per query.

응용

  • LCA in O(log N)
  • Kth ancestor in O(log N)
  • Path sum on tree (BIT + LCA)
  • Functional graph next state

참고

이 개념을 다룬 위키 페이지 (1)

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기