前置知識
-
FMT:對於兩個下標在 \([0,2^n)\) 的數組 \(f\) 和 \(g\),求:
-
\[h_i=\sum_{j\text{ or }k=i}f_jg_k \]
-
可以做到 \(O(2^nn)\)
-
限於博主水平,這里不放該前置算法的流程,請自行百度
引入
-
對於兩個下標在 \([0,2^n)\) 的數組 \(f\) 和 \(g\),求:
-
\[h_i=\sum_{j\text{ and }k=\varnothing,j\text{ or }k=i}f_jh_k \]
-
\(j,k\) 的條件即為集合 \(j\) 和 \(k\) 恰好拼成集合 \(i\)
-
\(h\) 為 \(f\) 和 \(g\) 的子集卷積
-
可以做到 \(O(2^nn^2)\) 的復雜度
算法流程
-
下面用 \(|i|\) 表示 \(popcount(i)\),即 \(i\) 二進制下 \(1\) 的個數
-
注意到 \(j\text{ and }k=\varnothing\) 時必有 \(|j|+|k|=|j\text{ or }k|\)
-
故引入占位多項式:
-
\[F_{i,j}=\begin{cases}f_j & |j|=i\\0 & |j|\ne i\end{cases} \]
-
求 \(H_{i,j}\) 時,可以枚舉拼成 \(j\) 的兩個集合大小 \(i_1\) 和 \(i_2\),我們有:
-
\[H_{i,j}=\sum_{i_1+i_2=i}\sum_{a\text{ or }b}F_{i_1,a}G_{i_2,b} \]
-
也就是:
-
\[H_i=\sum_{i_1+i_2=i}F_{i_1}\bigotimes G_{i_2} \]
-
\(\bigotimes\) 為或卷積
-
\(H_i\) 中可能會有 \(1\) 的個數小於 \(i\) 的項為 \(0\),但這並不重要
-
對於每個 \(0\le i\le n\),把 \(F_i\) 和 \(G_i\) 做一遍 FMT,作一遍上式之后得到 \(H\) 再 IFMT 回來即可得到 \(h\)
-
\(O(2^nn^2)\)
拓展
-
觀察這個式子
-
\[H_i=\sum_{i_1+i_2=i}F_{i_1}\bigotimes G_{i_2} \]
-
發現 \(\sum_{i_1+i_2=i}\) 就是我們常見的多項式卷積!
-
於是把 \(F\) 視為一個 \(n\) 次多項式(每個項的系數都是一個集合冪級數,即 \(F_i\))
-
也就是占位多項式,我們就可以進行求逆甚至 \(\ln\) 和 \(\exp\)
-
求逆可直接使用 \(g_i=\frac{1-\sum_{j=0}^{i-1}g_jf_{i-j}}{f_0}\) 進行遞推
-
對於 \(\ln\) 我們有 \(g=\ln f=\frac{f'}f\)
-
對於 \(\exp\) 我們有 \(g=\exp f\) 則 \(g'=gf'\),可以遞推出 \(g\) 的每一項
LOJ#3165「CEOI2019」游樂園
-
給定一個 \(n\) 節點 \(m\) 邊的有向圖,可以將部分邊反向,求使得原圖無環的所有方案下,翻轉的邊數之和,\(n\le 18\)
-
首先無環圖所有邊反向之后還是無環圖,這樣的兩個合法圖一一對應並且翻轉的邊數之和為 \(m\),故答案為方案數乘 \(\frac m2\)
-
\(f_S\) 表示點集 \(S\) 無環的方案數
-
一個圖無環當且僅當這個圖能夠拓撲排序,嚴謹地說就是每次刪掉圖中入度為 \(0\) 的點集可以刪完所有點
-
考慮枚舉 \(0\) 入度的點集(必須為獨立集),強制這個點集向外的邊只能連出不能連入
-
這樣無法保證外面的點入度不為 \(0\),考慮容斥掉有多出 \(0\) 入度點的情況
-
省略推導過程,
-
\[f_S=\sum_{T\subseteq S,T\text{ is an independent set}}(-1)^{|T|-1}f_{S-T} \]
-
設集合冪級數 \(g=\sum_{S\text{ is an independent set}}(-1)^{|S|-1}x^S\),對 \(g\) 的占位多項式每一項求 FMT 之后就能推出 \(f\) 占位多項式的每一項的 FMT
-
\(O(2^nn^2)\)
-
也可以從另一個角度理解:上式相當於 \(f=f\bigotimes g+1\),也就是 \(f=\frac1{1-g}\),上面推出 \(f\) 的某一項,本質上是在進行一個求逆的過程
-
(此處為后話)
-
而 \(1-g\) 的第 \(T\) 項,若 \(T\) 為獨立集(包括空集)則為 \((-1)^{|T|}\),否則為 \(0\)
-
對於常數項為 \(1\) 的集合冪級數 \(A\),有個性質是 \(A^k\)(子集卷積意義下)的每一項都是關於 \(k\) 的多項式(可以根據空集在 \(k\) 次中被選出的次數進行證明)
-
故我們得出一個結論:給圖用 \(k\) 種顏色染色(邊兩端的點顏色不同)的方案數 \(f(k)\) 是一個關於 \(k\) 的多項式,給圖定向成為 DAG 的方案數為 \((-1)^nf(-1)\)
LOJ#154 集合划分計數
-
給定一個集合冪級數 \(f\),求把全集划分成不超過 \(k\) 個集合(集合之間無序),這些集合在 \(f\) 中對應項的乘積之和
-
這是一個不完整的 \(\exp\):
-
\[g=\sum_{i=0}^k\frac{f^i}{i!} \]
-
還是考慮和 \(\exp\) 一樣求導:
-
\[g'=\sum_{i=1}^k\frac{if^{i-1}f'}{i!}=f'\sum_{i=0}^{k-1}\frac{f^i}{i!} \]
-
於是我們有:
-
\[g'=f'(g-\frac{f^k}{k!}) \]
-
也可以從小到大推 \(g\) 占位多項式的每一項
-
參考 EI 的博客
