ABCDEGの6完。今週は2回のratedコンテストがあるけど、両方ABCなので気楽。Fを飛ばしてGを解くという、内容のわりにパフォがだいぶ高く出る動きができる相性のいいセットで、久々の黄パフォ(青に落ちてからというもの、ABCでも黄パフォが取れなくなった)。
A - Horizon
12800000を頑張ってコピペ。また、式の意味を考えている時間はないので、頑張って写す。
B - Integer Division
かなり怖い見た目。ライブラリ(整数を指定方向で最も近いmの倍数にする関数)を貼る。
C - Knight Fork
見た目の割には簡単。候補は図にあるだけなので全部試す(周囲100個くらいの格子点を試した)。
D - Prime Sum Game
ミニマックス的なことをここまで低難度でやらせてくれるのは教育的。B+Dまでの素数判定ができるようにしておき、まあ全ての手順を探索するんだけど、高橋君がこれを選んだとき青木君に勝ちがあるかを求めて、青木君に勝ちがない選択が高橋君にあったかを求める。
E - Subtree K-th Max
Vを0-indexedに直してないうえ代わりにiを使っていたというミスでWA。そこでTLEも出ていたが、マージするとき大きい側へ入れる処理をしてないことに気づかずTLE。2ペナだった。変数名Vにもうちょっと警戒してもよかった。マージテクでできると気づいて、しかしそれが想定とも考えづらいので少し粘ったが頭に粘りがなかったのでマージテクを書いた。上位20個持てばいいというの気づかなかったね。頂点番号とクエリの頂点番号の変数名を分けたうえにクエリ番号とは分けなかったのが酷かった。実装がきつかった。
(追記)解説を見て実装すると、こんなに楽な問題だったのかとわかった。std::mergeを使った。
F - Construct Highway
Dの合計が(N-1)*2でないとか、元々D_i本以上あるとか、閉路があるとか、色々なダメ条件があって怖い(この問題の本質に行く前にそこを全てカバーしておかないといけない)。森のいくつかの頂点からいくつかのひらひらが出てる図を描いてどうペアを作るか考えていたが、全くわからなかった。終了5分前くらいになって、復元のことを考えなければ連結成分はまとめて1頂点扱いにしてしまっていいことに気づいた(こんな基本的なことにどんだけ時間かかるんだ)。ただ、そこからも難しい。サイズが大きいほうから貪欲につなげていくのがいいかなあとか思ったけど、その真偽はわからなかった。
(追記)どうも上に書いた貪欲は正しいらしいが理由はわからない。実装は2時間くらいかかった。コンテスト中に通した人えらすぎる。
G - Builder Takahashi
壁を置くのが頂点でなく辺ならただの最小カット。解けそう。図を描くと、頂点を入口と出口に分けて、入口に入辺をまとめて出口も同様にすれば、あとは入口と出口の間にコストぶんの辺を張るだけだ。無向グラフなのが難しそうだが、有向グラフでも双方向に張るだけで同じ状況になるので大丈夫だった。頂点数はN*2。元の辺は出口から入口へ容量∞の辺にして、元の頂点内には入口と出口へ双方向に容量C_iで張る。使わないところは∞にする(元の頂点1とNの中)。流して、入口と出口が違うのに属してたらコストを払う。
(追記)入口と出口は双方向に結ぶ必要なかった。入口から出口へ流すだけでいい(人体と同じ)。
Ex - Dice Product 2
Fと交互に考えていた。シンプルな見た目で解けそうに思うが数がそこそこ大きいので難しそう。