2020年5月25日月曜日

CodeChef May Cook-Off - Chefina on a Trip

無向辺を2つの有向辺と見て、スコアが下がる向きに重み1-1、上がる向きに+1+1、変わらないなら00を付与すると、ある有向パスが上りになっているmin\Leftrightarrow \minクエリが11である、下りになっているmax\Leftrightarrow \maxクエリが1-1である、と判定できる。

ダブリングLCAの構築をする時に、同時にmin/maxについてもダブリングのテーブルを作っておけばパスuvu - vがbeautifulかどうかは適当に判定できる:

  1. uuから根に向けてスコアが上がる限りダブリングで上る。LCA(u,v)\operatorname{LCA}(u, v)の深さより上(inclusive)に行けたら3に行く。
  2. さらに根に向けてスコアが下がる限り上る。LCA(u,v)\operatorname{LCA}(u, v)の深さより上に行けなかったらfalseを返す。LCA(u,v)\operatorname{LCA}(u, v)の深さより上に行けたら頂上がuLCAu- \operatorname{LCA}の側にあると記録しておく。
  3. vvから根に向けてスコアが上がる限り上る。LCA(u,v)\operatorname{LCA}(u, v)の深さより上に行けたらtrueを返す。頂上がuLCAu-\operatorname{LCA}の側にあるのにLCA(u,v)\operatorname{LCA}(u, v)の深さより上に行けなかったらfalse。
  4. さらに根に向けてスコアが下がる限り上る。LCA(u,v)\operatorname{LCA}(u, v)の深さより上に行けたらtrueを返す。
  5. falseを返す。

山のイメージに従って書くだけなので特に難しいとは感じなかった。でも、振り返ってみると、uuvvを完全に対称に扱ったほうがいい気がする。