Kotlin Heroes はコンテストには参加せず,C++ や Python で書いたコードを chatgpt に変換してもらうことで AC しています.コンテスト中にこれをやるのはルール違反です.
A. Color Revolution
$(1,k,k^2,k^3)$ の何倍かを調べます.
B. Boot Camp
手前から貪欲に最大化します.
C. Spring Cleaning
1 種類目の操作のみ行う場合を計算しておきます.あとは大きいものいくつかに 1 種目の操作をした後 2 種類目の操作を 1 回行う場合を計算します.
D. Constructing the Dungeon
各頂点の値は接続する辺の値の max 以上であることが必要です.max より大きくする意味がないので max に合わせて判定します.
E. Magic Tricks
dp[i] を位置 i に持っていくための最小操作回数として,スワップできる場所についてだけ更新していけばよいです.
F. Dune II: Battle For Arrakis
行方向・列方向独立に解くことができます.制約でクエリのたびに $\Theta(n+m)$ 時間かけることが許されているので,目的地ごとのコストをすべて計算してしまってよいです.
G. Two IP Cameras
$x_1,x_2,x_3$ のうち少なくとも 2 つが同じ成分に属します.それを固定して 3 回解きます.片方の等差数列が決められたら残ったものが等差数列に含められるかを gcd を利用して判定します.
H. Game with Segments
Alice の手番での長さの parity を固定して解きます.
適当な dp テーブルを考えますが,(l,r) と (l-1,r+1) が同じインデックスになると都合が良いです.そこで Alice の手番で index = (l + r + parity) / 2 となるような dp テーブルの持ち方をします.
dp の値は,ゲーム終了時の区間の長さなどとしておきます.
長さが 2 増えたときに,newdp[i] = min(max(dp[i-1],dp[i]), max(dp[i],dp[i+1])) の形の dp 更新をすることになります.つまり両隣より真に小さい部分があればそこを更新する形です.また terminal segment があるところの dp[] を点更新という処理もあります.
前者の dp 更新が行われるならば dp 値の種類数が減るため,すべての更新箇所を列挙できていれば愚直に更新しても償却計算量は大丈夫です.次に dp の更新が入る場所の候補は,前回 dp 更新が入った場所の近くしかないので,それを保持して次の長さに進むようにすればよいです.
I. Pac-Man 2.0
まずすべてのペレットが出現してから回収しきるまでのことを計算します.始点・終点に対するコストを計算します.これは適当な bit dp でできます.
次に,$2^k$ 回ペレットを全回収するためのコストを始点・終点ごとに計算します.行列の 2 乗を繰り返す感じです.
すると,各 $x$ に対してスタート地点から $x$ 回ペレットを全回収するためのコストが終点ごとに計算できます.それを利用して答を計算すればよいです.