More Related Content Similar to LCA and RMQ ~簡潔もあるよ!~ (7) More from Yuma Inoue (20) LCA and RMQ ~簡潔もあるよ!~2. ERATO若手輪読会 2014/11/19
• LCA: Lowest Common Ancestor (最近共通祖先)
• 根付き木 T 上の2頂点 u, v に対するクエリ LCA(u,v)
• u と v の祖先であって、もっとも深い頂点 x を返す
• RMQ: Range Minimum Query (区間最小値)
• 列 A[1:n] 上の区間 [l, r] に対するクエリ RMQ(l,r)
• A[l:r] 中での最小値 A[i] を取るような i を返す
• LCA と RMQ には密接な関係がある
LCAとRMQ
2
u
v
x
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
l r
i
T
4. ERATO若手輪読会 2014/11/19
LCAとRMQ
• クエリ処理アルゴリズムの計算量表記: <f(n), g(n)>
• f(n): 前処理時間, g(n): 1つのクエリの処理時間
4
LCA を <f(n), g(n)> で解くアルゴリズムが存在
→ RMQ は <f(n)+O(n), g(n)+O(1)> で解ける
RMQ を <f(n), g(n)> で解くアルゴリズムが存在
→ LCA は <O(f(n))+O(n), O(g(n))+O(1)> で解ける
定理1
定理2
5. ERATO若手輪読会 2014/11/19
RMQ to LCA
5
LCA を <f(n), g(n)> で解くアルゴリズムが存在
→ RMQは <f(n)+O(n), g(n)+O(1)> で解ける
定理1
• 列Aを Cartesian Tree に変換
• Cartesian Tree
• 値の2分ヒープ構造
• 頂点ラベルはインデックス
• 子の左右が列の左右と一致 id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
1
3
2
5
4
6
6. ERATO若手輪読会 2014/11/19
RMQ to LCA
6
• RMQ(l,r):
Cartesian Tree上でLCA(l,r)を解く
ことで最小値インデックスが求まる
• Cartesian Treeの構築: O(n)
• 最小値そのものが知りたいとき:
メモリアクセス O(1)
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
1
3
2
5
4
6
LCA を <f(n), g(n)> で解くアルゴリズムが存在
→ RMQは <f(n)+O(n), g(n)+O(1)> で解ける
定理1
7. ERATO若手輪読会 2014/11/19
LCA to RMQ
• 木 T を Euler Tour で展開
• Euler Tour:
• TをDFSで辿る
• 頂点の訪問順で列を定義
• 列の長さは必ず2n-1
7
RMQ を <f(n), g(n)> で解くアルゴリズムが存在
→ LCA は <O(f(n))+O(n), O(g(n))+O(1)> で解ける
定理2
4 65
2
1
3
T
id 1 2 3 4 5 6 7 8 9 10 11
A[id] 1 2 1 3 4 3 5 3 6 3 1
8. ERATO若手輪読会 2014/11/19
LCA to RMQ
• LCA(u,v):
深さ配列d上でRMQ(l,r)
(l, rはu, vのAでの出現位置)
• Euler Tourへの展開: O(n)
• LCAの頂点番号取得:
メモリアクセス O(1)
8
RMQ を <f(n), g(n)> で解くアルゴリズムが存在
→ LCA は <O(f(n))+O(n), O(g(n))+O(1)> で解ける
定理2
4 65
2
1
3
T
id 1 2 3 4 5 6 7 8 9 10 11
A[id] 1 2 1 3 4 3 5 3 6 3 1
d[id] 0 1 0 1 2 1 2 1 2 1 0
13. ERATO若手輪読会 2014/11/19
1RMQ
• LCA: Euler Tour の深さ配列でRMQ
• 1回の移動で深さはちょうど1だけ変わる
• 深さ配列の隣接要素同士は+1 か -1 だけ異なる
• 隣接要素の変化が 1 である列上での RMQ を 1RMQ
と呼ぶ
• 1RMQ が <O(n), O(1)> で解ければ、LCA も <O(n),
O(1)> で解ける
134 65
2
1
3
id 1 2 3 4 5 6 7 8 9 10 11
A[id] 1 2 1 3 4 3 5 3 6 3 1
d[id] 0 1 0 1 2 1 2 1 2 1 0
+1 +1 +1 +1 +1 -1 -1-1-1-1
14. ERATO若手輪読会 2014/11/19
<O(n), O(1)> RMQ
RMQを <O(n), O(1)> で解く流れ
1. RMQ を Cartesian Tree に変換し、LCA に帰着
( 時間・空間: O(n) )
2. LCA を Euler Tour で展開し、 1RMQ に帰着
( 時間・空間: O(n) )
3. 1RMQ を以下のテクニックで <O(n), O(1)> で解く
• ブロック分割
• Sparse Table
• Table Lookup
14
[Bender et. al. '05]
15. ERATO若手輪読会 2014/11/19
ブロック分割
• 簡潔データ構造の典型テクニック
• 長さnの列を長さs = logn/2のブロックに分割
• ブロックの数 B = 2n/logn
• 各ブロックの最小値インデックスを O(n) で前計算
• 全体の RMQ クエリは、以下のクエリに分割される
• ブロックの区間に対する RMQ クエリ1回
• ブロック内部に対する RMQ クエリ2回
15
id 1 2 3 4 5 6 7 8 9 101112131415161718192021222324252627282930
A[id] 1 2 1 3 4 3 5 3 6 3 1 8 4 9 11 4 1 5 6 3 2 5 2 5 2 1 9 8 4 1
16. ERATO若手輪読会 2014/11/19
ブロック分割
• 簡潔データ構造の典型テクニック
• 長さnの列を長さs = logn/2のブロックに分割
• ブロックの数 B = 2n/logn
• 各ブロックの最小値インデックスを O(n) で前計算
• 全体の RMQ クエリは、以下のクエリに分割される
• ブロックの区間に対する RMQ = Sparse Table
• ブロック内部に対する RMQ = Table Lookup
16
id 1 2 3 4 5 6 7 8 9 101112131415161718192021222324252627282930
A[id] 1 2 1 3 4 3 5 3 6 3 1 8 4 9 11 4 1 5 6 3 2 5 2 5 2 1 9 8 4 1
それぞれ <O(n), O(1)> で
解ければOK
17. ERATO若手輪読会 2014/11/19
Sparse Table
• i 番目から長さ2kの区間の最小値インデックスをそれ
ぞれ記憶したO(n logn)のテーブルを持つ
• 構築: O(n logn)
• S[i][k+1] = argmin( A[S[i][k]], A[S[i+2k][k]] )
• クエリ: O(1)
• RMQ(i, j) = argmin( A[S[i][k]], A[S[j-2k+1][k]] )
• k = floor( log(j-i) ) ← O(1)で求められると仮定
17
id 1 2 3 4 5 6 7 8
A[id] 1 2 1 3 4 3 5 3
id 1 2 3 4 5 6 7 8
A[id] 1 2 1 3 4 3 5 3
構築: クエリ:
18. ERATO若手輪読会 2014/11/19
Sparse Table
• i 番目から長さ2kの区間の最小値インデックスをそれ
ぞれ記憶したO(n logn)のテーブルを持つ
• B個のブロックに対し、<O(B logB), O(1)> のアルゴ
リズム
• B = 2n/lognより、
B logB = 2n/logn・(log2n - loglogn) = O(n)
18
id 1 2 3 4 5 6 7 8
A[id] 1 2 1 3 4 3 5 3
id 1 2 3 4 5 6 7 8
A[id] 1 2 1 3 4 3 5 3
構築: クエリ:
19. ERATO若手輪読会 2014/11/19
Table Lookup
• 簡潔データ構造の典型テクニック その2
• 1 で変化している列の最小値インデックスは、値
そのものを見なくても変化量だけ見ればわかる
• すべての変化パターンと区間 [l,r]について、最小値
インデックスを記録して参照すればよい
• 長さ s の列の変化のパターンは2s通り
• よって、<O(s22s), O(1)> のアルゴリズム
• s = logn/2より、s22s = O(log2n n) = o(n)
19
20. ERATO若手輪読会 2014/11/19
<O(n), O(1)> RMQ
RMQ を <O(n), O(1)> で解けた!!!
1. RMQ を Cartesian Tree に変換し、LCA に帰着
( 時間・空間: O(n) )
2. LCA を Euler Tour で展開し、 1RMQ に帰着
( 時間・空間: O(n) )
3. 1RMQ を以下のテクニックで <O(n), O(1)> で解く
• ブロック分割
• Sparse Table
• Table Lookup
20
[Bender et. al. '05]
22. ERATO若手輪読会 2014/11/19
簡潔RMQ
RMQ を <O(n), O(1)> で解けた!!!
1. RMQ を Cartesian Tree に変換し、LCA に帰着
( 時間・空間: O(n) )
2. LCA を Euler Tour で展開し、 1RMQ に帰着
( 時間・空間: O(n) )
3. 1RMQ を以下のテクニックで <O(n), O(1)> で解く
• ブロック分割
• Sparse Table
• Table Lookup
22
BP (Balanced Parentheses) 表現で2n bitに
BP上の rank( - rank) が深さに対応 → Euler Tour なしに 1RMQ
分割を多段にすることで o(n) bitに
[Sadakane '07]
23. ERATO若手輪読会 2014/11/19
簡潔RMQ
• 問題点: BP 上でわかるのは pre-order
RMQ で求めたいインデックスは
Cartesian tree 上では in-order
• 対応を覚える場合O(n logn) bit を使う → not 簡潔
• Cartesian Tree に dummy node を n 個付加するこ
とで解決 → 4n + o(n) bitに
23
[Sadakane '07]
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
1
3
2
5
4
6
( ( ( ) ( ( ) ( ) ) )
1
1
3
2
2
8
4
6
5
3
6
5
24. ERATO若手輪読会 2014/11/19
簡潔RMQ
• 問題点: BP 上でわかるのは pre-order
RMQ で求めたいインデックスは
Cartesian tree 上では in-order
• 対応を覚える場合O(n logn) bit を使う → not 簡潔
• Cartesian Tree に dummy node を n 個付加するこ
とで解決 → 4n + o(n) bitに
24
[Sadakane '07]
id 1 2 3 4 5 6
A[id] 1 8 2 6 3 5
1
3
2
5
4
6
( ( ( ) ( ( ) ( ) ) )
1
1
3
2
2
8
4
6
5
3
6
5
2n
にしたい
25. ERATO若手輪読会 2014/11/19
簡潔RMQ
• Cartesian Tree + BP の代わりに 2D-Min Heap +
DFUDS (Depth-First Unary Degree Sequence)
• 流れ:
• 入力列を 2D-Min Heap を表すDFUDSに変換
• O(n)時間、 DFUDSは 2n bit
• DFUDS に必要な索引を付加
• O(n)時間、索引は o(n) bit
• 索引付き DFUDS 上で LCAを解く
• 内部で rank, select, findopen, 1RMQ 等を使用
• O(1) 時間
25
[Fischer '09]
id 0 1 2 3 4 5 6
A[id] - 1 8 2 6 3 5
1
32
54
6
2D-Min Heap
0
DFUDS: ( ( ) ( ( ) ) ( ( ) ) ( ) )
26. ERATO若手輪読会 2014/11/19
簡潔RMQ
• Cartesian Tree + BP の代わりに 2D-Min Heap +
DFUDS (Depth-First Unary Degree Sequence)
• 2D-Min Heap:
• 自分より左かつ小さいもののうち、最も右にある
ものを親にする
26
[Fischer '09]
id 0 1 2 3 4 5 6
A[id
]
- 1 8 2 6 3 5
1
3
2 5
4 6
1
32
54
6
Cartesian Tree
2D-Min Heap
0
27. ERATO若手輪読会 2014/11/19
簡潔RMQ
• RMQ(i, j)は、2D-Min Heap 上では、
• LCA(i, j)が i → RMQ(i, j) = i
• それ以外 → RMQ(i, j) = LCA(i, j)の子で、jの先祖
27
[Fischer '09]
id 0 1 2 3 4 5 6
A[id
]
- 1 8 2 6 3 5
2D-Min Heap
1
32
54
6
0
i j LCA(2,4)
RMQ(2,4)
28. ERATO若手輪読会 2014/11/19
簡潔RMQ
• Cartesian Tree + BP の代わりに 2D-Min Heap +
DFUDS (Depth-First Unary Degree Sequence)
• DFUDS:
• 葉は ( )
• w 個の子 T1, ..., Tw の親は w+1 個の ( と 1個の ) の後、
子を続ける.ただし、子の表現は先頭の ( を1つ削る
28
[Fischer '09]
( ( ) ( ( ) ) ( ( ) ) ( ) )
id 0 1 2 3 4 5 6
d 1 2 1 2 3 2 3 4 3 4 3 2 1 0
A[id] - 1 8 2 6 3 5
1
32
54
6
0
29. ERATO若手輪読会 2014/11/19
• RMQ(i, j)
1. l ← select)(U, i+1), r ← select)(U, j)
2. w = 1RMQ(l, r)
3. if rank)(U, findopen(U, w)) = i, then return i
4. else rank)(U, w)
29
簡潔RMQ [Fischer '09]
U: ( ( ) ( ( ) ) ( ( ) ) ( ) )
id 0 1 2 3 4 5 6
d 1 2 1 2 3 2 1 2 3 2 1 2 1 0
A[id] - 1 8 2 6 3 5
1
32
54
6
0
i j
l r
1RMQ(l,r)
findopen
30. ERATO若手輪読会 2014/11/19
• RMQ(i, j)
1. l ← select)(U, i+1), r ← select)(U, j)
2. w = 1RMQ(l, r)
3. if rank)(U, findopen(U, w)) = i, then return i
4. else rank)(U, w)
30
簡潔RMQ [Fischer '09]
U: ( ( ) ( ( ) ) ( ( ) ) ( ) )
id 0 1 2 3 4 5 6
d 1 2 1 2 3 2 1 2 3 2 1 2 1 0
A[id] - 1 8 2 6 3 5
1
32
54
6
0
i j
l r
1RMQ(l,r)
findopen
DFUDS 上の RMQ では、
w は i と j のLCAの子であり、
jの祖先である
(ただし LCA が iのとき w=i )
[Jansson et. al. '07]
31. ERATO若手輪読会 2014/11/19
• RMQ(i, j)
1. l ← select)(U, i+1), r ← select)(U, j)
2. w = 1RMQ(l, r)
3. if rank)(U, findopen(U, w)) = i, then return i
4. else rank)(U, w)
31
簡潔RMQ [Fischer '09]
U: ( ( ) ( ( ) ) ( ( ) ) ( ) )
id 0 1 2 3 4 5 6
d 1 2 1 2 3 2 1 2 3 2 1 2 1 0
A[id] - 1 8 2 6 3 5
1
32
54
6
0
i j
l r
1RMQ(l,r)
findopen
親が preorder わかる
32. ERATO若手輪読会 2014/11/19
• RMQ(i, j)
1. l ← select)(U, i+1), r ← select)(U, j)
2. w = 1RMQ(l, r)
3. if rank)(U, findopen(U, w)) = i, then return i
4. else rank)(U, w)
32
簡潔RMQ [Fischer '09]
U: ( ( ) ( ( ) ) ( ( ) ) ( ) )
id 0 1 2 3 4 5 6
d 1 2 1 2 3 2 1 2 3 2 1 2 1 0
A[id] - 1 8 2 6 3 5
1
32
54
6
0
i j
l r
1RMQ(l,r)
findopen自分の preorder わかる
33. ERATO若手輪読会 2014/11/19
割愛したところ
• 入力列から直接 2n bit のDFUDSへ O(n) で変換
• 簡潔でない方法: スタックを利用したアルゴリズム
• 簡潔な方法: スタックを簡潔にする
• 1RMQ をより簡潔に
• o(n) で隠された部分がより succinct に
• 具体的には、(loglogn)2 かかっていたところが
loglogn に落とせる
33
34. ERATO若手輪読会 2014/11/19
まとめ
• LCA と RMQは適切に変換することで等価な問題
として解ける
• LCA to RMQ: Euler Tour, BP, DFUDS
• RMQ to LCA: Cartesian Tree, 2D-Min Heap
• LCA で要求される RMQ が 1RMQ であることを
利用し、<O(n), O(1)> を実現する
• 木の簡潔表現と LCA, RMQ の簡潔辞書により、
2n + o(n) bitで、<O(n), O(1)> を実現する
34