木の頂点を消したり戻したりしたいとき、ある?
僕はあります(硬い石)
何ができるのか
木が与えられて、頂点を消したり戻したりするときに、各連結成分に対するクエリを処理できる。
この記事ではある頂点が消えているとき「死んでいる」、そうでないとき「生きている」と呼ぶ。
例えば、こういうのとか
onlinejudge.u-aizu.ac.jp
やりかた
まずは適当な頂点を一つ追加して根付き木にする。
部分木を管理するLCTを用意する。
最初は全ての頂点が生きているものとして木を構築する。
最初から死んでいる頂点がある場合はその後で殺せばよい。
ある頂点を殺すときは、その頂点と親との間の辺をcutする
逆に生き返らせるときは(元の親と)linkする
ある時点で頂点vを含む連結成分に対するクエリに答えたいときは
- t = root(v) を求める
- t-vパスのなかのtの直接の子cを求める(expose(v)して二分木を下るなりLevelAncestorを使うなり)
- t-c 間をcutする
- query(c)でクエリに答える
- t-c 間をlinkする
の手順で操作を行えばよい。
どうしてこの手順でうまくいくのかは、考えればわかると思います(丸投げ)