【做题记录】雅礼集训2018 方阵
-
【雅礼集训 \(2018\)】方阵
- 算法:斯特林反演
题目:
给定 \(n\times m\) 的矩阵,每个格子填上 \([1,c]\) 的数字,求任意两行、两列均不同的方案数。
\(n,m\le 5000\)
题解:
设 \(g(m)\) 表示 \(n\times m\) 的矩阵中任意两行不相同的方案个数。
从第一行往下推,第一行显然有 \(c^m\) 种(\([1,c]\) 中每个都能选),而第二行则在 \(c^m\) 的基础上减去 \(1\) 种,(即第一行的方案),之后的类比。
第 \(i\) 行 | 对于 \(g(m)\) 当前行的方案数 |
---|---|
第一行的方案数 | \(c^m\) |
第二行的方案数 | \(c^{m}-1\) |
\(\dots\) | \(\dots\) |
第 \(n\) 行的方案数 | \(c^{m}-n+1\) |
不难看出 \(g(m)=c^m\times (c^m-1)\times \dots \times (c^m-n+1)\),
即 \(g(m)={(c^m)}^{\underline{n}}\)。
设 \(f(m)\) 表示 \(n\times m\) 的矩阵任意两行两列都不相同。
不妨从 \(g(m)\) 中枚举有多少个本质不同的列,设有 \(i\) 个。
对于 \(g(m)\),其方案数又可以由 \(f(i)\) 表示为
简单解释,就是 \(g(m)\) 相当于对于 \(n\times i\) 的 \(f(i)\) 之和,因为 \(g\) 不需要保证列不相同,所以大力枚举能每种 \(f\),然后对于每一种 \(f(i)\),都要相当于从 \(m\) 列中挑选出 \(i\) 列使它们互不相同,那么也就是 \(\begin{Bmatrix}m\\i\end{Bmatrix}\)。
但是我们是要求出 \(f(m)\),而且对于 \(g(i)\) 我们有更为简单的方式(\(g(m)={(c^m)}^{\underline{n}}\)),所以我们考虑通过 \(g\) 来求出 \(f\)。
那么可以用斯特林反演。
套用模板,得
就可以求出 \(f\)。
总的时间复杂度为 \(O(n^2)\)