今回は #485 を走った。C,Dが割と辛かった。
codeforces.com
AB2完。C,D,Eは解説AC。
A - Fair
制約の が露骨にヒントっぽいので多始点BFSを 回すれば通った。
B - Petr and Permutations
転倒数の偶奇とswap数の偶奇は一致するというよくある典型。 を で2secで出すの、少し攻めすぎじゃない?
C - AND Graph
これ面白い。 なら が の否定 に包含されてる ( )という言い換えすら思いつかなかったのは反省。
個の頂点集合 と 個の頂点集合 を用意して から への有向辺を張って、 から に が から bit削ってできるなら有向辺を張って、 から への有向辺を張ると、 から へのパスがあることが と同値になる。
で、 は交換則があるので、逆方向のパスも存在するっていうこと。なので、後はDFSなりBFSをすればいい。
のだが、グラフを陽に持つとMLEするので陰に持ちつつDFS内部で次に行ける頂点を探す必要がある。 にしてほしい。
D - Perfect Encoding
問題文の読解が難しい。要約すると
数列 に対し、 とする。 を満たす のうち が最小となるものについて を求めろ。
とりあえず最適な を考えると、 以上があるなら半分ごとに分割して損はないし、 が つ以上あるなら を にしても損はしないので、最適解は を つ以下で、残りは という形。
なので、 を満たす最小の整数 を求める問題を 回解けばいいのだが、 が 桁あるのが難しい。多倍長の掛け算は畳み込みで でできるので二分探索+繰り返し二乗法で頑張ったのだがTLE。
結論としては、桁数を とすると が の前後になるので、ここの間だけ全探索すればよいという。これでもTLEしたが、原因は数を 進数で考えていたからだった。 進数で考えるすなわち 桁をまとめて畳み込みすると定数倍高速化が効く。
それにしてもきつかった。制約とTLが厳しい。
E - Prince's Problem
とりあえず素数ごとに分離する。LCAを考えるとパスの端点を の場合に帰着できる。オイラーツアーの順にセグ木に乗せるテクを使うと数列の範囲に対して を取った場合の総和を求める問題になる。
ここで悩んでいたが、数列の値は の次数なので合計が になる。これを利用して 以上のやつに加算して との はただの範囲和として求める。 以上のやつに加算して との はただの範囲和として求める。というのを繰り返せばよいとなって面白かった。