toyama1710 blog posts tags categories

ダブリングでLCA求めるやつ(DoublingTree)

categories:


DoublingTreeのドキュメント
LCAを求めたり木上の任意の2ノード間の距離を $\Theta(\log N)$ で計算したりできる

doubling_tree.hppにはDoublingTreeクラスとDoublingTreeBuilderクラスを定義してある

DoublingTree

コンストラクタ

template<class InputItr>
DoublingTree(InputItr first, InputItr last)

vector<optional<int>>をiteratorで渡す (list<optional<long long>>とかでも動くと思うけどverifyしとらん)
DoublingTree(v.begin(), v.end())みたいに呼び出す
v[i]には頂点iの親が入る 頂点iが根の場合は親がないのでnulloptをいれておく

lca(int u, int v)

頂点u,vのLowestCommonAncestorを求める $\Theta(\log N)$
u, vが連結でない場合の動作は未定義

climb(int u, int d)

戻り値の型はoptional<int>
頂点uを根方向にd個遡った頂点を返すが、もしも根を飛び越してしまうような場合にはnulloptを返す $\Theta(\log N)$

distance(int u, int v)

頂点u, vの距離をintで返す $\Theta(\log N)$
u, vが連結でない場合の動作は未定義

DoublingTreeBuilder

入力形式によってはDoublingTreeのコンストラクタが扱いにくいので作った補助クラス

コンストラクタ

DoublingTreeBuilder(n)で頂点数n個の木を作る
最初、どの頂点も辺で接続されていない

add_edge(int u, int v)

頂点u,vを直接結ぶ辺を追加する

build(const vector<int> &root = {0})

指定した頂点を根としてDoublingTreeを構築して返してくれる
森を扱うことを考えて根は複数指定できるようにしてある