1. 程式人生 > >組合計數和反演

組合計數和反演

組合計數和反演

包含內容

二項式反演、斯特林反演、莫比烏斯反演、第一類斯特林數、第二類斯特林數。

反演

首先我們有兩個數列\(\{f_i\}\)和數列\(\{g_i\}\),他們之間滿足
\[g_n=\sum_{i=0}^n a[n][i]f_i\]
這裡我們可以通過\(\{f_i\}\)的值推出\(\{g_i\}\)
那麼反演過程就是找到一個數組\(b\),使得能夠用\(\{g_i\}\)的值,反推出\(\{f_i\}\)的值。
也就是
\[f_n=\sum_{i=0}^n b[n][i]g_i\]
如果只通過上面兩個式子來考慮的話,事實上這就是一個反解線性方程組的過程,然而實際上整個方程組已經是一個下三角的形式了,因此我們可以考慮更加快捷的方式來進行計算。

這裡給出克羅內克函式
\[\delta(i,j)=\begin{cases}1&i=j\\0&i\neq j\end{cases}\]
只是為了後面的書寫的方便而介紹這個函式。

考慮反演的過程
\[f_n=\sum_{i=0}^n b[n][i]g_i\]
我們把\(g_i\)的計算式直接帶入當前式子,那麼就會得到:
\[\begin{aligned}f_n=\sum_{i=0}^n b[n][i]g_i&=\sum_{i=0}^n b[n][i]\sum_{j=0}^ia[i][j]f_j\\&=\sum_{i=0}^n f_i\sum_{j=i}^nb[n][i]*a[j][i]\end{aligned}\]


考慮每一個\(f_i\)前面的係數,顯然只有\(f_n\)的係數為\(1\)
因此\(a,b\)之間的關係可以簡單的寫成。
\[\sum_{j=i}^nb[n][i]*a[j][i]=\delta(n,i)\]
同理,把\(f\)帶入到\(g\)的求和式中,可以推出
\[\sum_{j=i}^na[n][i]*b[j][i]=\delta(n,i)\]

如果滿足這兩個式子的話,那麼意味著反演也是成立的。
然而這樣子很虛幻,因為看起來也不知道有什麼用,那麼接下來就帶入具體的東西來寫QwQ。

二項式反演

這個玩意似乎經常在容斥裡面用到,或者說本質上就是一個容斥。
它的式子可以寫成這個樣子:
\[\begin{aligned}f_n&=\sum_{i=0}^n(-1)^i{n \choose i}g_i\\g_n&=\sum_{i=0}^n(-1)^i{n\choose i}f_i\end{aligned}\]


正反看起來是一模一樣的。
或者說寫成更加常見的一種形式
\[\begin{aligned}f_n&=\sum_{i=0}^n{n\choose i}g_i\\g_n&=\sum_{i=0}^n(-1)^{n-i}{n\choose i}f_i\end{aligned}\]
證明的話直接類似前面把\(f_i\)帶入\(g_n\)的求和式之中,通過組合數的化簡即可簡單的證明。
\[\begin{aligned}g_n&=\sum_{i=0}^n(-1)^{n-i}{n\choose i}f_i\\&=\sum_{i=0}^n(-1)^{n-i}{n\choose i}\sum_{j=0}^i{i\choose j} g_j\\&=\sum_{j=0}^n g_i\sum_{i=j}^n{n\choose i}{i\choose j}(-1)^{n-i}\\&=\sum_{j=0}^n g_j\sum_{i=j}^n{n\choose j}{n-j\choose i-j}(-1)^{n-i}\\&=\sum_{j=0}^n g_j({n\choose j}\sum_{i=j}^n{n-j\choose i-j}(-1)^{n-i})\\&=\sum_{j=0}^n g_j({n\choose j}\sum_{i=0}^{n-j}{n-j\choose i}(-1)^{n-j-i})\\&=\sum_{j=0}^n g_j({n\choose j}(1-1)^{n-j})\\&=g_n\end{aligned}\]

當然,還可以寫成這個樣子:
\[ \begin{aligned} f_k&=\sum_{i=k}^n{i\choose k}g_i\\ g_k&=\sum_{i=k}^n{i\choose k}f_i(-1)^{i-k} \end{aligned} \]
證明同理。

應用

  • 錯排問題

求完全錯位的排列方案數,即不存在\(p_i=i\)的排列\(\{p\}\)的個數。

這個是有遞推做法的,但是因為這裡在寫二項式反演,所以不考慮其他的做法。
\(f_i\)表示恰好有\(i\)個位置時滿足不存在\(p_k=k\)的方案數,也就是答案。
那麼我們推出一個式子:
\[n!=\sum_{i=0}^n{n\choose i}f_i\]
即列舉哪些位置滿足\(p_k=k\),剩下位置強制滿足錯排關係,這樣子就能夠不重不漏的計算出\(n!\)個排列。
這樣一來令\(g_n=n!\),有二項式反演的式子:
\[f_n=\sum_{i=0}^n(-1)^{n-i}{n\choose i}g_i=n!\sum_{i=0}^n\frac{(-1)^i}{i!}\]

  • 染色問題

\(1\times n\)的一排格子,有\(m\)種顏色,每個格子染一個顏色,相鄰格子顏色不能相同,每種顏色都至少被用到\(1\)次,求染色方案數。

如果不考慮每個顏色都要被用一次的話,答案顯然就是\(m*(m-1)^{n-1}\),這樣也就是至多用了\(m\)種顏色。
\(f_i\)表示恰好用了\(i\)種顏色的方案數,那麼與之對應的設\(g_i\)表示至多用了\(i\)種顏色的方案數。
那麼我們推出一個轉移:
\[g_m=m*(m-1)^{n-1}=\sum_{i=0}^n {n\choose i}f_i\]
二項式反演得到:
\[f_m=\sum_{i=0}^m(-1)^{m-i}{m\choose i}g_i\]

其他還有些題目之類的東西懶得寫了QwQ。

第一類斯特林數

遞推式

\(\begin{bmatrix}n\\m\end{bmatrix}\)表示\(n\)個元素分成\(m\)個環的方案數。
那麼遞推式很顯然:
\[\begin{bmatrix}n\\m\end{bmatrix}=\begin{bmatrix}n-1\\m-1\end{bmatrix}+(n-1)*\begin{bmatrix}n-1\\m\end{bmatrix}\]
即考慮先前已經放好的\(n-1\)個數,當前新加入的這個元素有兩種選擇,第一種是自己成一個環,貢獻是\(\begin{bmatrix}n-1\\m-1\end{bmatrix}\);第二種是放到環內,那麼它可以放在任意一個數的前面,所以就是\((n-1)*\begin{bmatrix}n-1\\m\end{bmatrix}\)
為了好寫,接下來可能就偷懶寫成\(S_1(n,m)\)了。

一點小性質

  • \(\displaystyle n!=\sum_{i=0}^n S_1(n,i)\)
    證明?第一類斯特林數的本質是環排列的個數,環的本質可以理解為置換。那麼顯然所有第一類斯特林數對應的環排列可以和置換一一對應,所以總數就是\(n!\)
  • \(\displaystyle x^{\underline{n}}=\sum_{i=0}^nS_1(n,i)(-1)^{n-i}x^i\),其中\(x^{\underline n}\)表示\(n\)次下降冪
    證明可以用數學歸納法來解決。
    \[\begin{aligned}x^{\underline{n+1}}&=(x-n)x^{\underline n}\\ &=(x-n)*\sum_{i=0}^n\begin{bmatrix}n\\i\end{bmatrix}(-1)^{n-i}x^i\\ &=\sum_{i=1}^{n+1}\begin{bmatrix}n\\i-1\end{bmatrix}(-1)^{n-i-1}x^{i}-n\sum_{i=1}^{n+1}\begin{bmatrix}n\\i\end{bmatrix}(-1)^{n-i}x^{i-1}\\ &=\sum_{i=0}^{n+1}\begin{bmatrix}n\\i-1\end{bmatrix}(-1)^{n-i-1}x^i+n\sum_{i=0}^{n+1}\begin{bmatrix}n\\i\end{bmatrix}(-1)^{n-i+1}x^i\\ &=\sum_{i=0}^{n+1}(\begin{bmatrix}n\\i-1\end{bmatrix}+n*\begin{bmatrix}n\\i\end{bmatrix})(-1)^{n+1-i}x^i\\ &=\sum_{i=0}^{n+1}\begin{bmatrix}n+1\\i\end{bmatrix}(-1)^{n+1-i}x^i \end{aligned}\]
  • \(\displaystyle x^{\overline n}=\sum_{i=0}^n S_1(n,i)x^i\),其中\(x^{\overline n}\)表示\(x\)\(n\)次上升冪
    可以類似上面的東西證明

這幾個式子還是很有用的,揭示了第一類斯特林數和下降冪之間的關係,而下降冪很明顯可以寫成排列的形式,也說明了第一類斯特林數和組合計數之間有著緊密的聯絡。

預處理

第一類斯特林數的生成函式可以寫成:
\[\sum_{i=0}^n S_1(n,i)x^i=\prod_{i=0}^{n-1}(x+i)\]
得到的方法很簡單,把\(n\)為定值時的所有的第一類斯特林數按照\(n\)分類分成行,發現每次的\(S_1(n,m)\)轉移必定要從\(n-1\)行轉移過來,而每次轉移都是\(m-1\)變到\(m\),係數為\(1\),因此有一項\(x\),同理有一項\(n-1\),因此就可以得到上面的那個生成函式。

考慮如何預處理整行第一類斯特林數,用上述式子可以直接分治+\(FFT\)做到\(O(nlog^2n)\)
實際上有一種只需要一個\(log\)的倍增方法。
\(\displaystyle F_n(x)=\prod_{i=0}^{n-1}(x+i)\),則有\(F_{2n}(x)=F_n(x)F_{n}(x+n)\)
\[\begin{aligned}F_n(x+n)&=\prod_{i=0}^{n-1}(x+i+n)\\&=\sum_{i=0}^{n-1}S_1(n,i)(x+n)^i\\&=\sum_{i=0}^{n-1}S_1(n,i)\sum_{j=0}^i{i\choose j}x^jn^{i-j}\\&=\sum_{j=0}^{n-1}x^j\sum_{i=j}^{n-1}{i\choose j}S_1(n,i)n^{i-j}\\&=\sum_{j=0}^{n-1}\frac{x^j}{j!}\sum_{i=j}^{n-1}i!S_1(n,i)\frac{n^{i-j}}{(i-j)!}\end{aligned}\]
聽說這個東西是個卷積可以遞迴過程中直接乘?不太理解.jpg,等我懂了就來補這裡。

第二類斯特林數

這個其實原來我寫過一次啦QwQ。
\(\begin{Bmatrix}n\\m\end{Bmatrix}\)表示將\(n\)個元素放入\(m\)個相同盒子裡,每個盒子非空的方案數。
遞推式和上面類似
\[\begin{Bmatrix}n\\m\end{Bmatrix}=\begin{Bmatrix}n-1\\m-1\end{Bmatrix}+m*\begin{Bmatrix}n-1\\m\end{Bmatrix}\]
考慮最後放入的元素是新建一個盒子還是放入一個原有的盒子即可。
後面偷懶寫成\(S_2(n,m)\)的形式。
上述式子是直接遞推,事實上第二類斯特林數有容斥計算的方法。
\[S_2(n,m)=\frac{1}{m!}\sum_{i=0}^m(-1)^i{m\choose i}(m-i)^n\]
即先將盒子編號,最後結果出去順序即可。考慮有幾個盒子為空,枚舉出來,然後剩下的元素隨便放在非空的盒子裡,因為這裡算完之後是至少\(i\)個盒子為空,所以需要容斥。
這個式子拆開組合數之後可以寫成卷積的形式,意味著我們可以在一個\(log\)的複雜度裡求解\(S(n,i),i\in[0,n]\)

這裡和自然數冪之間有一個式子
\[m^n=\sum_{i=0}^mS_2(n,i){m\choose i}i!\]
\(m^n\)理解為把\(n\)個球任意放到\(m\)個有區別的盒子中,那麼我們列舉哪些盒子非空,然後放進去的方案數就是第二類斯特林數乘階乘。
當然,事實上上面的這個式子也可以寫成上升冪和下降冪的形式
\[ \begin{aligned}m^n&=\sum_{i=0}^mS_2(n,i){m\choose i}i!\\&=\sum_{i=0}^mS_2(n,i)\frac{m!}{(m-i)!}\\&=\sum_{i=0}^mS_2(n,i)m^{\underline i}\end{aligned} \]

斯特林反演

直接擺式子吧
\[ \begin{aligned} f(n)&=\sum_{i=1}^n \begin{Bmatrix}n\\i\end{Bmatrix}g(i)\\ g(n)&=\sum_{i=0}^n(-1)^{n-i}\begin{bmatrix}n\\i\end{bmatrix}f(i)\end{aligned} \]
為了證明這個東西我們接下來可以補一堆式子啦。
首先這個東西叫做反轉公式
\[\begin{cases}\sum_{k=m}^n(-1)^{n-k}\begin{bmatrix}n\\k\end{bmatrix}\begin{Bmatrix}k\\m\end{Bmatrix}=\delta(n,m)\\\sum_{k=m}^n(-1)^{n-k}\begin{bmatrix}k\\m\end{bmatrix}\begin{Bmatrix}n\\k\end{Bmatrix}=\delta(n,m)\end{cases}\]
仔細想想,這不就是上面反演如果成立的話需要滿足的兩個式子嗎?
所以只需要證明反轉公式成立,那麼類似前面的帶入方法,就可以證明斯特林反演。
我們先考慮幾個很顯然的式子就可以很方便的幫忙證明反轉公式了。

  • \(x^{\underline n}=(-1)^n (-x)^{\overline n}\)

  • \(x^{\overline n}=(-1)^n (-x)^{\underline n}\)

這兩個式子很顯然,就不證明了。
接下來我們就可以來推式子了。
\[\begin{aligned} n^m&=\sum_{i=0}^m\begin{Bmatrix}m\\i\end{Bmatrix}n^{\underline i}\\ &=\sum_{i=0}^m\begin{Bmatrix}m\\i\end{Bmatrix}(-1)^i(-n)^{\overline i}\\ &=\sum_{i=0}^m\begin{Bmatrix}m\\i\end{Bmatrix}(-1)^i\sum_{j=0}^i \begin{bmatrix}i\\j\end{bmatrix}(-n)^j\\ &=\sum_{j=0}^m (-n)^j\sum_{i=j}^m\begin{Bmatrix}m\\i\end{Bmatrix}\begin{bmatrix}i\\j\end{bmatrix}(-1)^i\\ &=\sum_{j=0}^m n^j\sum_{i=j}^m\begin{Bmatrix}m\\i\end{Bmatrix}\begin{bmatrix}i\\j\end{bmatrix}(-1)^{i+j} \end{aligned}\]
顯然當且僅當\(j=m\)時後面那堆式子才為\(1\)
那麼就證明了反轉公式的一半,另外一半顯然可以同理證明。
這樣一來斯特林反演就證明完了。

莫比烏斯反演

可以說是我們最熟悉的反演了。主要用於和約數相關的關係。
\[ \begin{aligned} g(n)&=\sum_{d|n}f(d)\\ f(n)&=\sum_{d|n}g(d)\mu(\frac{n}{d}) \end{aligned} \]
證明,直接帶進去來爆算:
\[ \begin{aligned} g(n)&=\sum_{d|n}f(d)\\ &=\sum_{d|n}\sum_{dd|d}g(dd)\mu(\frac{d}{dd})\\ &=\sum_{dd|n}g(dd)\sum_{d|n,dd|d}\mu(\frac{d}{dd})\\ &=\sum_{dd|n}g(dd)\sum_{d|(n/dd)}\mu(d)\\ &=\sum_{dd|n}g(dd)\delta(n,dd)\\ &=g(n) \end{aligned} \]
這裡利用了\(\sum_{d|n}\mu(d)=\delta(n,1)\)
還有另外一種形式,和二項式反演的另外一種形式很類似。
\[\begin{aligned}g(n)&=\sum_{n|d}f(d)\\f(n)&=\sum_{n|d}g(d)\mu(\frac{d}{n})\end{aligned}\]
證明方法類似。

題目

單獨分開一篇總結QwQ