6完。全てが上手く行ってギリ黄パフォ。環境が厳しい。
A - 12435
swapしてis_sortedで確認してswapで戻す、というのを4回やる。スムーズに解けたと思ったのに2分以上かかってる。
B - Geometric Sequence
27 18 12 8 みたいのもあり、かなり怖い。サンプルを見て「長さ2以下なら等比数列なのか」「公比が整数でないこともあるのか」などと気づいていて、あまりにも危なっかしい。比を隣同士比べる。整数演算でできる。比べる回数がN-2なの「知らなかった」のでやはり怖い。
C - Paint to make a rectangle
パッと見では全然わからず難しい。気づけばまあ簡単。黒マスのBounding Boxがわかればいい。その中に白マスがあるならできないし、そうでないなら内側を黒に塗って外側を白に塗ればできる。制約を見落としていて、黒マスがないときは塗られていないマスがあるかどうかで決めた。
D - Stone XOR
Nが小さいけど簡単な列挙方法を思いつかない。そもそも1回操作しないとスワップができないとか考えてたけど順番は関係ないのを忘れていた(グループ分けを考えるだけでいい)。DFSで無理やりやる。残っている中で最も左のものを使うとして、そいつと同じ袋になるものをビット全探索する。これで重複なくグループ分けを列挙できるはず(この問題の場合、別に重複してもいいけど)。N=12で実行してDFSの葉が400万個程度であることを確認。unordered_setで数えて実行時間も短い。であれば問題ないので提出、ジャッジに時間かかると思ったら1835msでACしてびっくり。
終了後にsetで提出し直したらなんとTLEした。要素数が400万になるとunordered_setやsetが思ったより遅かった。そもそもの話として、葉が400万しかないなら全部vectorに突っ込んでsortしてuniqueすれば明らかに間に合う。いつものABCだと思って手癖でunordered_setを選んでしまったのがよくない。
E - Vitamin Balance
最小値をとるビタミンを3通り試せばいけるとなぜか思ってしまったができないので考え直す。データをビタミンの種類で分けてしまっていいのはそうなので、別々にDPすることを考える。DP自体は簡単。合計カロリーがこれのときのビタミンの最大摂取量が得られる。これを使って問題が解けるか考えると、二分探索で楽に解けそうだ。しゃくとりで行けそうなのとカロリーがちょうどjではなくj以下のときの最大に変換して安全に処理できるかすぐにわからなかったりして手間取った。結局は変換したし二分探索にした。
Fを読んで順位表を見たら、Eはめっちゃ解かれていて、やっぱ競プロerはDPキチガイだと思った。
F - Double Sum 3
問題文の言ってることはわかるが、それをそんな大量に足すとかできるわけがない。少し考えて、各要素の寄与を足すやつじゃないかと気づいた。例えば9があったら、8と同じ区間になれば操作回数が減る、10も同様。定量的なことが全然わからないけど、とりあえず実装してみる。左右それぞれについて最も近い指定した数の位置を得たい。親切にもA_iが小さいので各値についてインデックスのvectorを持つ。番兵として-1とNを入れてソート。1より1小さい数とかNより1大きい数とかを場合分けするのも面倒なので、0からN+1までのN+2個の値があるとした。1小さいのと1大きいのそれぞれについて、その相手と一緒にならない区間がいくつあるか数える(小さいのと大きいの独立にできそうなの最初は見えてなかった)。とりあえずサンプルをやってみて、2倍ちょっと違う。改めて考え、自分と同じ数と同じ区間になったときも操作回数を削れると気づいた。また、黒板に書かれた連続した数の塊について、両端の要素が1/2ずつのコストを負うことにすると、自分の実装は(Aの要素が相異なるなら)答えの2倍を求めるものになっていそうだ。そこで、区間内の同じ数は最も右のものにコストを負わせることとし、右側で1小さい(大きい)数よりも近くに同じ数があるなら、コストが減らない区間右端の領域はそこまでとした。なんか違う気がしていたけど、感覚に反してサンプルが通ったので提出してAC。
わからないままACしちゃった。考え直すと正しい気もしたけど、そのときの気分ももう忘れてしまった。