Official

H - Security Camera Editorial by sugarrr


まず半分全列挙を用います。
交差点を集合 \(S\) と集合 \(T\) に分けます。

\(L_1[s],L_2[s],R[t]\) を以下のように定義します。

  • \(L_1[s]:\) \(S\) の部分集合 \(s\) にカメラが設置されているとき、監視されている道の本数の偶奇 (bool)
  • \(L_2[s]:\) \(S\) \ \(s\) への道の本数が奇数であるような集合 \(T\) の要素 (長さ \(|T|\) のbitset、または int)
  • \(R [t]:\) \(T\) の部分集合 \(t\) にカメラが設置されているとき、\(T\) 内で監視されている道の本数の偶奇 (bool)

これらは \(O(|S| 2^{|S|}), O(|T| 2^{|T|})\) で計算できます。

さて、監視されている道の総数が偶数であるための条件は、
\(L_1[s] \oplus ((\text{popcount} (L_2[s] \& t) ) \&1) \oplus R[t] = 0\)
です。

\(F[t'][t], Fsum[t']\) を以下のように定義します。

  • \(F[t'][t] = ((\text{popcount} (t' \& t) ) \&1) \oplus R[t]\)
  • \(Fsum[t'] = \sum_{t \subseteq T}F[t'][t]\)

すべての \(t' \subseteq T\) について \(Fsum[t']\) が求まれば、答えが求まります。
そのためには \(F[t'][t]\) が求まれば十分ですが、\(F[t'][t]\) はそもそも要素数が \(4^{|T|}\) と大きいので \(F\) を埋め切ることは難しく、工夫が必要です。

ここで、\(F[t'][t]\) において、\(t'\) の最上位の bit に着目すると、以下の性質が成り立ちます。

\(M=2^{|T|-1}, t' \geq M\) として、
\(F[t'][t] = F[t' - M][t] ( t \lt M)\)
\(F[t'][t] = 1- F[t' - M][t] ( t \geq M)\)

イメージを掴むために \(R=(0,1,0,0,1,1,0,0)\) の時の例を図にしてみました。(赤枠の部分が同じで、青枠の部分は \(0\)\(1\) を入れ替えたものになっています。)

さらに、この性質が再帰的に成り立ちます。(次は \(t'\)\(2\) 番目の bit に着目してみましょう。)
よって再帰的に \(Fsum[t']\) を全て求めることができ、\(O(N 2^{\frac{N}{2}})\) で本問題を解くことができました。

なお、\(R\) から \(Fsum\) を得る操作はアダマール変換とほぼ同じで、上述の再帰的な工夫は高速アダマール変換と呼ばれているものとほぼ同じです。

posted:
last update: