Hewlaの競プロ記

競プロ記です。

Sum AND Subarrays (AtCoder Dwango Programming Contest V / 第5回 ドワンゴからの挑戦状 予選 - D)

散々なことをやりまくって時間を溶かしてしまいました

概要

長さNの数列の部分列からK個を選び、それぞれの部分列の和のANDを取ったものの最大値を求める問題。
B - Sum AND Subarrays

解説

ANDをとるので、選んだK個全てで立っているBITのみが残る

ANDの最大値をとるので、最高ビットを残すことが最優先

すべての部分列を列挙(O(N^2))
上のビットから順番に見ていって、そのビットが立っているような部分列がK個以上あればそのビットを残すことに決める
そして、そのビットが立っている部分列のみをK個の候補に残し、下位のビットに移る

一種の貪欲といえるのかな

部分和の最大値は10^{12} \simeq 2^{40}なので、longを使います
計算量は、部分列がO(N^2)個、見るビットの数がO(log(aN))個、僕はsetを使ったのでここにO(log(N))が加わって、O(N^2log(aN)log(N))でした。
実装を上手くやるとO(N^2log(aN))までおちると思います。2桁msで通してる人のコードを読むと大体わかります

ソースコード

感想/反省

ANDをORと勘違いしたり、setの要素をeraseしようとして散々バグらせたり、自作のビジュアライズ関数がバグってたり、散々なことになってしまいました。問題を解き続けることが必要だなと感じました。次はレートあげたいぞ〜