LCAλ Least Common Ancestorμ μ½μμ΄λ€. Treeμμμ κ³΅ν΅ μ‘°μμ μ°Ύλ λ¬Έμ μ μ¬μ©λλ μκ³ λ¦¬μ¦μ΄λ€. κ³΅ν΅ μ‘°μμ΄ μ¬λ¬κ° μμ μ μμΌλ―λ‘, κ·Έ μ€μ μ μΌ λΉ λ₯Έ μ‘°μμ LCAλ‘ μ μνλ€. inputμΌλ‘λ μλ‘ λ€λ₯Έ λ Nodeκ° μ£Όμ΄μ§λ€. μ΄ λ Nodeλ₯Ό lκ³Ό rμ΄λΌ νμ.
λ§μ½ Nodeμ depthλ₯Ό λͺ¨λ₯Έλ€λ©΄ μ΄ λ°©λ²λ°μ μ¬μ€ μ¬μ©ν μκ° μλ€. κ° lμ λν΄(lμ΄ rootκ° λ λκΉμ§) λͺ¨λ rμ μννλ€. μ½λλ₯Ό 보면 μκ² μ§λ§ 무쑰건 μ°Ύμ μλ°μ μλ€.
for(Node* l = sl; l != 0; l = l->parent) {for(Node* r = sr; r != 0; r = r->parent) {if (l == r) return l;}}
λ§μ½ depthλ₯Ό μλ€λ©΄, lκ³Ό rμ depthλ₯Ό κ°κ² λ§μΆ μ΄νμ, μμͺ½ Nodeλ₯Ό λ§λ λκΉμ§ κ°μ΄ μ¬λ¦¬λ©΄ λλ€. ꡬνμ νΈμλ₯Ό μν΄ μ²μμλ 무쑰건 lμ depthκ° ν¬λλ‘ swapμ νλ κ²μ΄ νΈνλ€. μ΄λ κ² κ΅¬ννλ©΄ 2μ€ν¬λ¬Έμ΄ μκΈ° λλ¬Έμ worstλ O(n)μ΄λ€.
if (l->depth < r->depth) swap(l, r);while(l->depth > r->depth) l = l->parent;for(;;l = l->parent, r = r->parent) {if (l == r) return l;}
O(log n)λ‘ κ΅¬ννλ €λ©΄ μλ 2μ§μμ λμλ°©μμ μ΄ν΄ν νμκ° μλ€.
λΉμ°ν μ리μ§λ§, 2μ§μλ λͺ¨λ 10μ§μλ₯Ό λνλΌ μ μλ€. λ§μ½μ μμμ Nodeμ λν΄μ λΆλͺ¨λ₯Ό μ μ νκ² μ μ₯νλ©΄ λΆλͺ¨λ‘ μ¬λΌκ°λ κ³Όμ μ O(n)μ΄ μλ O(log n)μΌλ‘ ν μ μλ€. λ°λ‘, λΆλͺ¨λ₯Ό μ μ₯νλλ°, μ 체 λΆλͺ¨λ₯Ό μ μ₯νλ κ²μ΄ μλλΌ, 1, 2, 4, 8, μ²λΌ 2μ§μμ μ°μ΄λ μ«μμ λΆλͺ¨λ€μ μ μ₯νλ κ²μ΄λ€. μ΄λ κ² μ μ₯νλ©΄, λ§μ½ νΉμ λ
Έλμ 8λ²μ§Έ λΆλͺ¨λ₯Ό ꡬνλ€κ³ νμ λ, νΉμ λ
Έλμ 4λ²μ§Έ λΆλͺ¨μ 4λ²μ§Έ λΆλͺ¨λ₯Ό ꡬνλ μμΌλ‘ μκ°ν μ μκ² λλ€. μ΄λ κ²λ§ μ μ₯ν΄λ, 7 = 0111(2μ§μλ‘) μ΄κΈ° λλ¬Έμ, λͺ¨λ μμμ μμ°μμ λΆλͺ¨λ₯Ό O(log n) μκ°μ μ°Ύμ μ μκ² λλ€. μ΄λ₯Ό μ½κ² ꡬννκΈ° μν΄μλ bitmaskλ₯Ό μ¬μ©νλ©΄ λλ€. μμμ μλ§νΌμ λΆλͺ¨λ‘ κ°λ μ½λλ μλμ κ°λ€.
struct Node {Node* parents[10]; // μ΅λ 2^9μ λΆλͺ¨λ₯Ό μ μ₯νλ€.};Node* findParent(Node* cur, int num) {int mask = 0x1;for(int i = 0; i < 10; ++i, mask <<= 1) {if (num & mask) cur = cur->parents[i]; // 2μ μ§μμΉλ§νΌμ λΆλͺ¨λ‘ μ΄λνλ€.}return cur;}
2^kμ λΆλͺ¨λ₯Ό μ μ₯νλ κ²μ μ½λμ node->parents[k]λ₯Ό 보λ κ²μΌλ‘ ꡬνμ΄ λλ€. μ΄λ₯Ό νμ©νλ©΄ LCAλ ꡬνν μ μλ€. μ ν
ν¬λμ νμ©νλ€.
if (l->depth < r->depth) swap(l, r);int diff = l->depth - r->depth;// 1. depthλ₯Ό λ§μΆ°μ€λ€.int mask = 0x1;for(int i = 0; i < 10; ++i, mask <<= 1) {if (num & mask) l = l->parents[i]; // 2μ μ§μμΉλ§νΌμ λΆλͺ¨λ‘ μ΄λνλ€.}if (l == r) return l;// 2. κ°μμ§κΈ° μ§μ κΉμ§ μ¬λΌκ°λ€.for(int i = 10 - 1; i >= 0; --i) {Node* nl = l->parents[i];Node* nr = r->parents[i];if (nl == nr) continue;l = nl; r = nr;}while(l != r) {l = l->parents[0];r = r->parents[0];}return l;
κ·Έλ°λ°, μ€λͺ
μ€μ νκ°μ§ λΉ λ¨λ¦° κ²μ΄ μλ€. parents[]μ μ΄κΈ°νλ μ΄λ»κ² ν κ²μΈκ°? μ΄λ₯Ό μ½κ² νκΈ° μν΄μλ μλμ κ°μ μμμ νμ©νλ€.
2^k = 2^(k-1) + 2^(k-1)
μ¬μ€ λΉμ°ν μμμΈλ°, μκ°νκΈ΄ μ¬μ€ μ½μ§ μλ€. μ΄ μμμ νμ©ν΄μ parents[]λ₯Ό μ΄κΈ°ν ν μ μλ€.
for(int i = 0; i < 10; ++i) {if (n->parents[i - 1] != nullptr)n->parents[i] = n->parents[i - 1]->parents[i - 1];else n->parents[i] = nullptr;}
μλ‘μ΄ κ°μ΄ μΆκ°λ λ, μμ κ°μ΄ Nodeλ₯Ό μ
λ°μ΄νΈ νλ©΄ λλ€. λ§μ½ Addκ° λ€ λ μνμμ parents[]λ₯Ό μ±μμΌ νλ€λ©΄, root λΆν° μμν΄μ μμμΌλ‘ μ±μ°λ©΄ λλ€.