A. String Rotation Game
$O(N)$ 時間でもいいし,全 rotate を試す $O(N^2)$ 時間でもよいです.
B. String Rotation Game
全体の操作回数を $k$ とすると,「全部を $k$ 回 flip」「選んだ場所を flip」と思えます.
すると,もともと $0$ だった場所同士で flip の有無が異なると詰みだと分かります.
もともと $1$ だった場所同士でも同様です.これで答となる集合が $O(1)$ 通りに限定されました.
C. All-in-one Gun
「最適な shoot 回数を求める」「所要時間を求める」で独立に計算すると分かりやすいと思います.
shoot 回数最適化は,例えば二分探索でできます.全体を何周か(固定ダメージ)のあと,先頭いくつかをとるということになります.
とる個数を固定して列を左右に分けたときに,何もしない,または左側の最小値を渡して右側の最大値をもらうというパターンをチェックすればよいです.
結局,prefix min, suffix max などを計算すればよいことになります.
D. Cost of Tree
辺を切る場所 $X$ と,つなぐ場所 $Y$ の LCA $v$ のところを考えます.
$X,Y$ が $v$ から見て別方向の部分木内,という状況を考えればよいです.$X$ の subtree の各頂点が,距離 $vY$ 分だけ得するという形です.
ここで,$X$ としてはなるべく $v$ と接する辺だけを対象とすればよいです.切る場所を親方向に動かした方が得なので.
これで,「LCA $v$ とする切り貼りでいくつ得ができるか」を $O(\deg(v))$ 時間で計算できそうになりました.$r$ 部分木内得をしようと思ったらそのような値の subtree max です.そんな感じで全体で $O(N)$ 時間になります.
E. Swap to Rearrange
値 $1,2,\ldots,N$ を頂点とするグラフを考えます.$a_i\to b_i$ または $b_i\to a_i$ に向きづけて,すべての頂点の入次数と出次数を同じにせよということです.
そもそも次数が偶数(つまり $a,b$ における出現回数の和が偶数)でないと詰みです.そうでないとすると,連結成分ごとにすべての頂点の次数は偶数なので,eulerian circuit がとれて,それに沿って向きをつければよいです.
単に辺集合を circuit に分割するだけでよい(複数の walk をつなぐような処理は必要ない)ので,eulerian circuit の実装は不要で,同じ点に戻るまで好きに辺を辿るという操作を繰り返すだけでも大丈夫です.
F. Fish Fight
まず,操作の途中経過(勝負がついていない状態)は $2$ つの交わらない区間 $[l_1,r_1), [l_2,r_2)$ として書けます(食べた魚の和集合区間を考える).
これだけで多項式時間にはなっています.どちらも長さがほとんど同じであることを使うと $O(N^3)$ 時間にはなるでしょう.
あとは,$2$ 人の魚は,近い位置に来るまではほとんど独立にシミュレートできることに注目して高速化します.
私の実装では次のように $P[i],Q[i],R[i]$ を定義しています.
Alice $n$ 回,Bob $m$ 回操作した時点において
- $P[i]$:Bob の魚を無視したときに $[i,i+n)$ に至る確率.
- $Q[i]$:Alice の魚を無視したときに $[i,i+m)$ に至る確率.
- $R[i]$:Alice が $[i,i+n)$,Bob が $[i+n,i+n+m)$ となっている確率.
$r_1<l_2$ ならば,冒頭に説明した状態 $[l_1,r_1), [l_2,r_2)$ に至る確率は積 $P[l_1]Q[l_2]$ と書けるので,これら $3$ つのテーブルが冒頭に述べた状態すべての情報を持っています.
あとはこれを普通にシミュレーションして更新していけばよいです.「Alice が動いて Bob が動く」を $1$ ターンとするのではなく,Alice, Bob それぞれの手番に分けて実装すると,無理なく実装できる実装量になると思います.
