beet's soil

競プロのことなど

木の頂点を消したり戻したりするときに使えるテクニック

木の頂点を消したり戻したりしたいとき、ある?
僕はあります(硬い石)

何ができるのか

木が与えられて、頂点を消したり戻したりするときに、各連結成分に対するクエリを処理できる。
この記事ではある頂点が消えているとき「死んでいる」、そうでないとき「生きている」と呼ぶ。

例えば、こういうのとか
onlinejudge.u-aizu.ac.jp

こういうのが解ける
https://codeforces.com/contest/1172/problem/E

やりかた

まずは適当な頂点を一つ追加して根付き木にする。
部分木を管理するLCTを用意する。

最初は全ての頂点が生きているものとして木を構築する。
最初から死んでいる頂点がある場合はその後で殺せばよい。

ある頂点を殺すときは、その頂点と親との間の辺をcutする
逆に生き返らせるときは(元の親と)linkする

ある時点で頂点vを含む連結成分に対するクエリに答えたいときは

  1. t = root(v) を求める
  2. t-vパスのなかのtの直接の子cを求める(expose(v)して二分木を下るなりLevelAncestorを使うなり)
  3. t-c 間をcutする
  4. query(c)でクエリに答える
  5. t-c 間をlinkする

の手順で操作を行えばよい。

どうしてこの手順でうまくいくのかは、考えればわかると思います(丸投げ)

お ま た せ
実 家 の よ う な 安 心 感
親 の 顔 よ り 見 た 部 分 木 の 情 報 を 管 理 す る L C T