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: