Official

E - popcount ≥ K Editorial by sounansya


まず、全てのクエリの \(C\) が同じ値である場合を考えます。

\(d[A][x][B]\) で「\([0,2^A)\) の中で \(C\) で割ったあまりが \(x\) となるような整数の集合のうち、popcount の値が \(B\) 以上であるようなものが先頭・末尾に何個続いているか、内部で最長何個続いているか、全て popcount \(B\) 以上であるか」の \(4\) つの情報を持ちます。この \(d\) の状態数は \(O(CK\log NK)\) であり、DP の遷移も\(A\) の昇順に行うことで各状態 \(O(1)\) でできます。

この \(d\) を元に答えを求めることを考えます。

まず、\(X\)\(C\) で割ったあまりを \(x\) として固定します。

\(\text{INF}\) を問題の答えが \(2^{\text{INF}}\) 未満であるような定数とします。

問題の答えは \([0,2^{\text{INF}})\) の中に存在します。

これが \([0,2^{\text{INF}-1}), [2^{\text{INF}-1},2^{\text{INF}})\) のどちらに入っているかを考えます。\(X,X+C,\ldots,X+(N-1)C\) は以下の \(3\) パターンに分かれます:

  • \(X,X+C,\ldots,X+(N-1)C\) が全て \([0,2^{\text{INF}-1})\) に入っている。
  • \(X,X+C,\ldots,X+(N-1)C\)\(2^{\text{INF}-1}\) を跨いでいる。つまり、\([0,2^{\text{INF}-1}), [2^{\text{INF}-1},2^{\text{INF}})\) どちらにも部分的に入っている。
  • \(X,X+C,\ldots,X+(N-1)C\) が全て \([2^{\text{INF}-1},2^{\text{INF}})\) に入っている。

上の \(3\) パターンのうちどこに属するかは \(d[\text{INF}-1][*][*]\) の情報から簡単に調べることができます。

あとは狭くなった区間に対し上と同じことを再帰的に行うことで答えを求めることができます。

\(d\) を各 \(C\) に対して求めておくことで各テストケース \(O(\text{INF}\times C)\) で解くことができます。

実装例 (C++, 819ms)

posted:
last update: