概要
シンプルなアルゴリズムですが、Level Ancestor Problem 自体の知名度が低そうなので宣伝を兼ねて紹介します。
Level Ancestor
Level Ancestor とは、根付き木について定義される概念です。
の祖先であって、深さが であるもの ( の深さ )
の深さが分かれば「 から根の方向に 回親を辿った頂点は何か」というクエリを Level Ancestor を求める問題に帰着できます。 逆もまた帰着可能なので、多くの状況でこれらは同一の問題とみなすことが出来ます。
アルゴリズム
頂点の根付き木と 個のクエリ が与えられたとき、全てのクエリの結果を で得るアルゴリズムを示します。
木を DFS で走査しながら、「(根~現在居る頂点)のパス」を配列で管理します。
これは単に頂点に入ったとき push_back し、出るとき pop_back すればよいです。
は に居る時の配列の 番目の要素になります。
実装例
応用
の写像の累乗は で計算できる。
このような写像は functional graph と呼ばれる構造を成し、これはサイクルと内向木に分解可能である。
乗とは各頂点 について 回辺を辿った頂点を計算することであるから、 の深さを とすると ならばサイクルを だけ回ればよく、 なら が答えとなる。
これは前述した offline LA で で計算可能。
余談
online に LA のクエリを処理する、構築 クエリ のデータ構造も存在します。 こちらも大変興味深いアルゴリズムを使用しているので、いつか記事にしたいですね。