ツバサの備忘録

主に備忘録代わりに精進記録を載せていくつもりです。

第5回 ドワンゴからの挑戦状 予選 B - Sum AND Subarrays

問題
提出コード

解法

たかだか1000個の数字しかないので、まずはあり得る部分列の和をすべて書き出します。
その後、一番大きい数字を2進数に直したときの、一番左側のビットから順番に、使用できるかどうかを判定していきます。
左側から順番に使用すると決めていけば、それより大きい数字を作ることはできなくなります(1000は、0111よりも大きいので)。
ということで、降順にソートします。
今見るビットを1\lt\lt hとします。 そこからK個大きい順に見ていき、すべて1\lt\lt h以上であれば、このビットを使用することができるので、答えに加算します。
そうでなかったら、このビットを使用することはできません。
この後は、1\lt\lt hを使用するかどうかで操作が変わります。

  • 使用する場合
    現在1\lt\lt h以上の数字から、1\lt\lt (h-1)を使用するかどうかを決めます。
    1\lt\lt h以上の数字すべてについて、1\lt\lt hを引いていき、引いた区間のみに対して降順にソートをし直します。あとは、1\lt\lt (h-1)を使用するかどうかを上と同じ手順で調べれば大丈夫です。

  • 使用しない場合
    今見た全ての区間について、1\lt\lt (h-1)を使用するかどうかを決めます。
    まずは、1\lt\lt h以上の数字は、1\lt\lt hを引き算して、そのビットを消します。あとは、全ての区間を降順でソートしなおしていき、1\lt\lt (h-1)を使用するかどうかを上と同じ手順で調べれば大丈夫です。

これを繰り返してでてきた数字が最終的な答えになります。