ABC195

順位表のお気に入りのうちEが解けてFが解けてないの俺だけ。パフォーマンス1973相当は、悪くはないけどねえ。Fにめちゃくちゃ時間かかってしまった。

A - Health M Death

どっちで割ればいいか難しいやつ。まあこれはその中では簡単かな(伝われ)。H%Mで判定。

B - Many Oranges

難しくて時間かけてしまったと思ったけど、順位表見るとBにしてはめちゃくちゃ難しかったみたいね。Wグラムの粘土からAグラムのみかんが最大何個採れるか、floor(W/A)個。Bグラムのみかんが最小何個あればWグラムの粘土にできるか、ceil(W/B)個。これらを出力すればいい(当時はここまではっきりわかってなくて適当にやってた)。順番は両方試せばわかる(は?)。大小関係が逆転してたら"UNSATISFIABLE"(等しいのはその個数が条件を満たすのでOK)。最後にWがキログラムで与えられているという上昇負荷をくぐって提出、運良くAC。

解説読んだ。だから、これがB問題なのか。

C - Comma

難しそうだけどコンマの位置毎に考えれば簡単だ。下位から見て1個目のコンマは1000以上N以下の整数に1個ずつ入っている。2個目のコンマは10^6以上N以下の整数に1個ずつ入っている。以下同様に個数を計算し足していく。10^15を1000倍して10^18になってもオーバーフローしないので、Nと比較してループを抜ければ大丈夫。

D - Shipping Center

DPっぽい見た目だと思ったけど貪欲と全探索だった(AtCoderのABCらしいいい問題)。一番小さい箱を考えると、そこに入る一番価値の高い荷物を入れるとしてよい。なぜなら、その荷物が他の場所(他の箱か箱の外)にあるなら箱の中身(他の荷物または無)と交換できて合計価値が下がらない。つまり、箱を小さい順に、荷物を価値の高い順にソートし、貪欲に荷物を入れていけばいい(計算量も50^3とかなので工夫をしなくても間に合う)。LRも箱を選ぶときに判定するだけ。

E - Lucky 7 Battle

問題を理解して簡単そうだと思ったけど、実装もちゃんとした理解も重かった。後ろから考える。最後に手番になった人は2つの選択肢のうち好きなほうを選べる。7で割ったあまりは7通りあるが、そのうちのどれが勝ちでどれが負けかがわかるので、フラグを7個持つ。10倍すると7で割ったあまりが重複なく動くのでその置換をフラグたちにかける。手番が入れ替わったらフラグを全部反転させる。最後は上の桁が何もないので7で割ったあまりは0でそのフラグでそのときの手番の勝敗がわかる。それだけなんだけど、実装してるときは不安で一杯だった。実装上、SとXの末尾に0とTを追加した。

F - Coprime Present

最大で73個しかないので、公約数があるとしても72以下。特に72以下の素数だけ考えればいい。それで包除に行ってしまった。素数を使わないほうが簡単な可能性も考える。単純に全ペアgcdを求めて、gcdが1でないなら禁止されたペアとして数える。しかし、できそうでできない。昨日使って最近苦手意識が付いてる包除原理で固まってしまった。

残り10分くらいで72以下の素数の個数を調べて、20個と意外と少ないのでbitDPみたいのを思いついた。そこから40分くらいかかった。2つに分けるとすると計算量が多すぎる。ビットを分けるのではなく73個全部試せばいい。73個試して足していくとなんかうまくいかない。これはナップサックみたいに73回のループは外にするんだ。DPテーブルは使い回せる。今の1個を使ってどれだけ増えるかを73回やるだけ。どの素数の倍数でもないものは、そのまま処理してもよさそうだが、スキップして最後にその個数ぶんシフトしてもいい。

(追記)「そこから40分くらいかかった」と書いたが、正しくは30分だった。残り10分ということで、mod 30分 で -10分 になるのは22時20分だろうという感覚が働いてしまい勘違いした。