AtCoder Beginner Contest 281 参加記録
コンテストページ: https://atcoder.jp/contests/abc281
コンテスト中AC: A〜D
コンテスト後にEをAC(自力)
D - Max Multiple
- が小さい
- 倍数はの情報があれば良い
これらからDPだろうと判断しました。
情報としては、
- 何項目までを考慮したか
- 選んだ項の総和の
- 選んだ項の個数
が分かればよいので、
の項目までを考慮し、選んだ項の総和のがであり、選んだ項の個数がであるときの選んだ項の総和の最大値
遷移は以下のとおりです。
を選ばない場合
を選ぶ場合
初期値は、としておき、その他はなどで埋めておけばよいです。
なお、がの場合は遷移元としないようにする必要があることに注意します。
答えは、です。
提出コード: Submission #37160568 - AtCoder Beginner Contest 281
E - Least Elements
コンテスト中multisetで解こうとして結局だめでした。コンテスト後にWavelet Matrixで解けました。
からまでを昇順に並べた数列をとします。の先頭項の和をとします。
について、を削除し、を追加した場合に、からにどのように変化したかがわかれば、から変化分を増減させることで、を計算できます。
これを考える時、がそれぞれの番目以内かそうでないかの4通りを考えれば良いです。
具体的に説明します。
がの番目以内
この時、の分、和は減少します。がの番目以内
が削除され、が挿入することを考えると、削除されて空いた箇所に左詰めまたは右詰めで各要素が移動し、が挿入されたと考えることができます。
このケースでは、新たにが番目以内となってその分の和が増加するので、
と計算できます。がの番目より後ろ
が削除されて空いた箇所にそれより後ろの要素が左詰めされて、が挿入されます。
このケースでは、における番目の要素がで新たに番目となり、この分の和が増加するので、これをとおけば、
と計算できます。
がの番目より後ろ
このケースでは、による和の減少はありません。がの番目以内
が挿入されると、の削除によって空いた箇所に右詰めされるように動きます。 このケースでは、新たにが番目以内となってその分の和が増加し、で番目だった要素がにおける番目となって、この分が減少するので、
と計算できます。がの番目より後ろ
は和に影響しないので、
となります。
を全て記録することはの領域が必要となるので、不可能だと思います。また、仮にそれが可能だとしても、C++のvectorなら昇順ソートが毎回必要ですし、multisetでは何番目の要素かを得るのに時間がかかります。
そこで、Wavelet Matrixを使います。Wavelet Matrixはで構築し、で指定区間の任意のx番目に小さい要素を得ることが可能です。(但し、はに含まれる要素の最大値)
これで、で解くことができます。