Tarjan's off-line LCA の実装メモと速度
Tarjan’s off-line LCAを書いてみたので, その時のメモです.
ネタバレ注意
No.898 tri-βutree - yukicoder のちょっとしたネタバレが含まれます…
Tarjan’s off-line LCA(lowest common ancestors)は, LCAをoff-lineで$O((N + Q) \alpha (N))$で求めるアルゴリズムです. ($\alpha$は逆アッカーマン関数)
Tarjan’s off-line lowest common ancestors algorithm - Wikipedia
DFSの帰りがけに, Union Find
で木の辺をunite
していく. すると, Union Find
で表現している集合は, いまたどっている頂点とのLCAが同じになる頂点の集合になります.
具体例はこんな感じ. いま頂点$6$を見ているとします. 二重線はまだつなげていない辺です.
緑の集合は, 頂点$6$とのLCAが頂点$0$である集合です. また, 青の集合は, 頂点$6$とのLCAが頂点$4$である集合です.
DFSの戻りってこういうことできるんだなあ
# 実装
注意点はクエリを処理するタイミングで, LCAを求めたい頂点2つのどちらもがdfsされた時であること(なのでans == -2
を挟んでいる)
|
|
使用例です. $N = 10^5$, LCAのクエリ数$Q = 3 * 10^5$で196msならいいんじゃない? #426438 No.898 tri-βutree - yukicoder
# HLDが速いんじゃ
HLDなんでこんなに速いんですかね. $O(N + Q \log N)$のはずなんですが… 100ms #426441 No.898 tri-βutree - yukicoder
# しめ
クエリを二回見てるのがダメなんですかね… LCAやるときはHLDでいいでしょう…
でも, DFS帰りがけがかなり面白い. どこかで使えるといいな