1. 程式人生 > >Square(斯特林反演)

Square(斯特林反演)

快速 容斥 等價 left math wear 符號 arr 神題

題意

給出一個 \(n × m\) 大小的矩形,每個位置可以填上 \([1, c]\) 中的任意一個數,要求填好後任意兩行互不等價且任意兩列互不等價,兩行或兩列等價當且僅當對應位置完全相同,求方案數 。

\(n, m \le 5000\)

題解

這題是 Wearry 出的神題,根本不會做。。。把題解搬過來了。

首先我們有一個很簡單的方式使得列之間互不等價,對於任意一列,總方案數是 \(c^n\) , 那麽使得列與列之間互不相同的方案數為 \({(c^n)}^{\underline{m}}\)

接下來的問題只與行數有關 , 定義 \(g(n)\) 表示 \(n\) 行不保證每行互不等價的方案數 , \(f(n)\)

表示 \(n\) 行保證任意兩行互不等價的方案數 , 有 :
\[ \begin{align} g(n) &= {(c^n)}^{\underline{m}}\ &= \sum_{i=0}^{n} {n \brace i} f(i)\\end{align} \]
考慮這個式子的意義,就是枚舉了有幾行是不同的,然後將 \(n\) 行分成這 \(i\) 種不同的行(每個非空)的方案。

然後考慮斯特林反演就行了。(此處指不帶符號的第一類斯特林數)
\[ \begin{align} g(n) &= \sum_{i=0}^{n} {n \brace i} f(i) \\Leftrightarrow f(n) &= \sum_{i=0} (-1)^{n-i} \begin{bmatrix}n\\ i\end{bmatrix} g(i) \end{align} \]


然後在 \(O(nm)\) 的時間裏求出第一類斯特林數,就可以做完了。

其實還有更快的求法,但是對於這題沒有必要。

見此博客 orz orz 生成函數大師 SunwayShichengLight 。

總結

對於行列計算方案的題,常常可以考慮枚舉一維,用容斥或者斯特林反演做。

對於另外一維可以快速計算可行的方案,來除掉一維的限制。

代碼

自己寫

Square(斯特林反演)