ABC279

6完。結果的に順位表を見なかった。思ったより耐えてた。

A - wwwvvvvvv

wだったら余計に1足す感じで。体感と違って1分切ってなかった。

B - LOOKUP

部分文字列につられてsubstrと書いてしまいIDEに赤線引かれた。当然、substrじゃなくてfind。簡単なABで嬉しい。

C - RANDOM

行じゃなくて列なのが(本質は変わらないはずなのに)難易度を上げている。最初unordered_multisetを使おうと思ったが、unordered_mapで個数を管理するほうが楽だ。入力を保存したら、列をそれぞれ取り出してstringに入れてS由来なら+1、T由来なら-1する。最終的に全部0になっていればYes。

ソートを思いつかないのひどかったね。

D - Freefall

まあ三分探索。上限はA/Bを切り捨てたもの(こういう上限を設定しないとオーバーフローすると思ったけど全部doubleで計算すれば大丈夫だとあとで気づいた)。gを1増やしたら遅くなったってなる一番早いやつを二分探索で求める。しかしなぜかWA。微分する方針に変えてやり直してAC。かなり時間を使ってしまった。厳密に考えることができていない。つらい。

(追記)提出をコンテスト後に見るとテストケースの名前がわかる。Aが大きくてBが小さいケースで落ちているようだったのでA=10^18, B=1でやってみたら思いっきり間違ってる。10^18はdoubleの精度を超えている(そもそもlong longとdoubleは同じ8バイトなので指数の情報があるぶん不利なのは当たり前)。こんなことも気づかないのか。本当にゴミだった。整数じゃないんだから二分探索じゃなくてちゃんとした三分探索をする必要があった。

E - Cheating Amidakuji

読むのが大変。要するに、一連のswap操作を途中の1個だけ飛ばしてやったとき先頭の要素がどこへ行くかという問題。問題文をよく見て、"k"と"+1"で後者が大きいことを見極める必要がある(B[A[k]+1]と書いてある)。前と後ろから累積和みたいにするイメージ。それが実現できるか。まず、前からやって先頭だった要素がどこにあるかを記録していく。つぎに後ろから。かなりややこしいが、後ろからswapしていけば逆順の操作になっている。最終的にその要素がどこへ行くかがわかっている状態。これをさっきの記録と合わせて、4回目の操作を飛ばすとき3回目までの操作で位置8に来てたなら5回目からの操作で位置2に行く、みたいに答えを得ていく(具体例になってねえな)。前からの記録は位置1個だけなので小さく、後ろからやってく状態は長さNで大きいものの1か所ずつ更新しながら答えが得られるので上手くいく。

(追記)解説かなりアドホックに感じる。

F - BOX

UnionFindじゃねえの?計算量がlogになるやつを思ったが結局普通ので。ボールはたくさんあるがN+Q個だけを考えればいい。とりあえず書いていくと、タイプ3の操作が厄介であることに気づく。UnionFindでボールのグループは処理できている。各箱に入っているグループのリーダーが誰かもわかっている(箱が空になるケースを注意深く処理する)。それに加え、リーダーがどの箱にいるかもわかるようにすればいいか。更新するものが多く、かなり丁寧なコーディングが求められる。

G - At Most 2 Colors

前からDPしたくなる。0色1色2色の通り数を持って?3色目が現れるときは、直前のK-1個が全部同じ色である必要がある。ということでDPできそうだと思って書いていたけど、重複がないように数えるのが実は難しかった。

(追記)一応ACした。dp[i][j]を、最初のi個にちょうどj色現れる通り数としてまずDPを書く(jは0,1,2)。これに、3色目が現れたけど問題の条件は満たしているパターンを追加する。直前のK-1個は全部同じ色である必要があり、つまりK-1個前の色をその後K-2個続ける必要がある(K個前でなくK-1個前に注目するというアイデアによってACできた)。K-1個前のボールまでで2色である場合と3色目が現れる場合が対応している。で、3色目が現れた場合は改めて直前の2色で最初からやってましたという顔をしていれば同様の議論ができるので、2色の場合に足してしまっていい。コンテスト中サンプルが合わなかったのは、K-1個前のボールが「3色目」として配置されたものかもしれないからかな。サンプルが合わなかったときもそれっぽい理屈は言ってたわけで、たまたまACしただけのこの解法が正しい保証もない(たぶん正しいけど、証明にはなっていないということを言いたい)。