「学习笔记」组合计数:格路计数、二项式反演、斯特林数与 Min-max 容斥

发布时间 2024-01-07 09:40:36作者: K8He

「学习笔记」二项式反演、斯特林数、Min-max 容斥

点击查看目录

Something:

题单里的部分题目还没有写所以本文在例题方面没有施工完毕,发出来仅仅是因为这篇博太常需要翻阅但是又被积压在草稿箱底部 .

补完后会删除这段话 .

格路计数

一个比较经典的 trick .

在一个 \(n\times m\) 的方格内,只能向上或向右走,求从 \((0, 0)\) 走到 \((n, m)\) 的方案数 .

答案是 \(\dbinom{n + m}{n}\),组合意义是 \(n+m\) 次移动中选出 \(n\) 次向上移动 .

另一种解决方式是简单 DP,\(f_{i, j} = f_{i - 1, j} + f_{i, j - 1}\) .

在求解类似 \(\sum_{i = 1}^{n}\sum_{j = 1}^{m}\dbinom{a_i + a_j + b_i + b_j}{a_i + b_i}\) 的问题时,如果 \(nm\) 较大但值域较小,可以考虑转化为格路计数,在所有 \((-a_i, -b_i)\) 处初始化,使用 DP 算出所有 \((a_j, b_j)\) 的值 .

板子是 AGC001E .

二项式反演

终于能填这个坑了啊 .

大量参考:link1, link2 .

形式一与形式二是更常用的形式 .

形式零

假设全集 \(U = {A_1, A_2, \cdots, A_n}\) 的任意 \(i\) 个元素并集、交集都相等,设 \(f(n)\) 表示任意 \(i\) 个集合的补集的交集,\(g(n)\) 表示任意 \(i\) 个集合的交集 .

特别的,\(f(0) = \left|U\right|\)\(g(0) = \left|U\right|\) .

\(A\) 补集为 \(A^c\),有一条容斥等式:

\[\left|A_1\cap A_2\cap\cdots\cap A_n\right| = \left|U\right| - \sum_{i = 1}^{n}\left|A^c_i\right| + \sum_{i = 1}^{n}\sum_{j = 1}^{n}\left|A^c_i\cap A^c_j\right| - \cdots + (-1)^{n}\left|A^c_1\cap A^c_2\cap\cdots\cap A^c_n\right| \]

左边就是 \(g(n)\),右边相当于 \(\sum_{i = 0}^{n}\dbinom{n}{i}f(i)\) . 即 \(g(n) = \sum_{i = 0}^{n}(-1)^i\dbinom{n}{i}f(i)\) .

补集的补集就是原集,那么同理可得 \(f(n) = \sum_{i = 0}^{n}(-1)^i\dbinom{n}{i}g(i)\) .

那么可以得到形式零:

\[f(n) = \sum_{i = 0}^{n}(-1)^i\dbinom{n}{i}g(i)\Leftrightarrow g(n) = \sum_{i = 0}^{n}(-1)^i\dbinom{n}{i}f(i) \]

其他形式都可以在这个形式基础上变形得出 .

形式一

\[f(n) = \sum_{i = 0}^{n}\dbinom{n}{i}g(i)\Leftrightarrow g(n) = \sum_{i = 0}^{n}(-1)^{n - i}\dbinom{n}{i}f(i) \]

有一个组合意义:\(f(i)\) 为在一个集合中钦定 \(i\) 个元素被选择,其他元素随便选的方案数,\(g(i)\) 为在该集合中选出恰好 \(i\) 个元素的方案数 .

两个代数证明:

证明 1

\(h(n) = (-1)^{n}g(n)\),带入形式零:

\[f(n) = \sum_{i = 0}^{n}\dbinom{n}{i}h(i)\Leftrightarrow \frac{h(n)}{(-1)^n} = \sum_{i = 0}^{n}(-1)^i\dbinom{n}{i}f(i) \]

观察发现 \((-1)^{n + i} = (-1)^{n - i}\),因此得出形式二:

\[f(n) = \sum_{i = 0}^{n}\dbinom{n}{i}h(i)\Leftrightarrow h(n) = \sum_{i = 0}^{n}(-1)^{n - i}\dbinom{n}{i}f(i) \]

\[\tag*{$\square$} \]

证明 2

硬带:

\[\begin{aligned} f(n) &=\sum_{i = 0}^{n}\dbinom{n}{i}g(i)\\ &=\sum_{i = 0}^{n}\dbinom{n}{i}\sum_{j = 0}^{i}(-1)^{i - j}\dbinom{i}{j}f(j)\\ &=\sum_{i = 0}^{n}\sum_{j = 0}^{i}\dbinom{n}{i}\dbinom{i}{j}(-1)^{i - j}f(j)\\ &=\sum_{j = 0}^{n}f(j)\sum_{i = j}^{n}\dbinom{n}{i}\dbinom{i}{j}(-1)^{i - j}\\ &=\sum_{j = 0}^{n}f(j)\sum_{i = j}^{n}\dbinom{n}{j}\dbinom{n - i}{i - j}(-1)^{i - j}\\ &=\sum_{j = 0}^{n}\dbinom{n}{j}f(j)\sum_{k = 0}^{n - j}\dbinom{n - i}{k}1^{n - j - k}(-1)^{k}\\ \end{aligned} \]

\(\sum_{k = 0}^{n - j}\dbinom{n - i}{k}1^{n - j - k}(-1)^{k}\) 这一坨,当 \(n = j\) 时等于 \(1\),否则等于 \((1-1)^{n - j} = 0\) .

带回:

\[\begin{aligned} f(n)&=\sum_{j = 0}^{n}\dbinom{n}{j}f(j)\sum_{k = 0}^{n - j}\dbinom{n - i}{k}1^{n - j - k}(-1)^{k}\\ &=\sum_{j = 0}^{n}\dbinom{n}{j}f(j)[n = j]\\ &=\dbinom{n}{n}f(n)\\ &=f(n)\\ \end{aligned} \]

\[\tag*{$\square$} \]

形式二

\[f(n) = \sum_{i = n}^{m}(-1)^i\dbinom{i}{n}g(i)\Leftrightarrow g(n) = \sum_{i = n}^{m}(-1)^i\dbinom{i}{n}f(i) \]

证明考虑直接代入:

\[\begin{aligned} f(n) &=\sum_{i = n}^{m}(-1)^i\dbinom{i}{n}g(i)\\ &=\sum_{i = n}^{m}(-1)^i\dbinom{i}{n}\sum_{j = i}^{m}(-1)^j\dbinom{j}{i}f(j)\\ &=\sum_{j = n}^{m}f(j)\sum_{i = n}^{j}\dbinom{i}{n}\dbinom{j}{i}(-1)^{i + j}\\ &=\sum_{j = n}^{m}f(j)\sum_{i = n}^{j}\dbinom{j}{n}\dbinom{j - n}{i - n}(-1)^{2j + (i - j)}\\ &=\sum_{j = i}^{m}\dbinom{j}{n}f(j)\sum_{k = 0}^{j - n}\dbinom{j - n}{k}(-1)^{k}\\ &=\sum_{j = n}^{m}\dbinom{j}{n}f(j)[j = n]\\ &=\dbinom{n}{n}f(n)\\ &=f(n)\\ \end{aligned} \]

\[\tag*{$\square$} \]

形式三

\[f(n) = \sum_{i = n}^{m}\dbinom{i}{n}g(i)\Leftrightarrow g(n) = \sum_{i = n}^{m}(-1)^{i - n}\dbinom{i}{n}f(i) \]

证明与形式一比较类似:

\[\begin{aligned} f(n) &=\sum_{i = n}^{m}\dbinom{i}{n}g(i)\\ &=\sum_{i = n}^{m}\dbinom{i}{n}\sum_{j = i}^{m}(-1)^{j - i}\dbinom{j}{i}f(j)\\ &=\sum_{j = n}^{m}f(j)\sum_{i = n}^{j}\dbinom{j}{i}\dbinom{i}{n}(-1)^{j - i}\\ &=\sum_{j = n}^{m}\dbinom{j}{n}f(j)\sum_{i = n}^{j}\dbinom{j - n}{j - i}(-1)^{j - i}\\ &=\sum_{j = n}^{m}\dbinom{j}{n}f(j)\sum_{k = 0}^{j - n}\dbinom{j - n}{k}1^{j - n - k}(-1)^{k}\\ &=\sum_{j = n}^{m}\dbinom{j}{n}f(j)[n = j]\\ &=\dbinom{n}{n}f(n)\\ &=f(n)\\ \end{aligned} \]

\[\tag*{$\square$} \]

斯特林数

第一类斯特林数

定义

「第一类斯特林数(斯特林轮换数)」记作 \(\begin{bmatrix}n\\k\end{bmatrix}\)\(s(n, k)\),表示将两两不同的 \(n\) 个元素划分为 \(k\) 个互不区分的轮换的方案数 .

「轮换」指的是一个首尾相接的序列,例如说 \([A, B, C, D] = [B, C, D, A] = [C, D, A, B] = [D, A, B, C]\),但是 \([A, B, C, D]\neq[D, C, B, A]\) .

递推式

\[\begin{bmatrix}n\\k\end{bmatrix} = \begin{bmatrix}n - 1\\k - 1\end{bmatrix} + (n - 1)\begin{bmatrix}n - 1\\k\end{bmatrix} \]

特别的,\(\begin{bmatrix}n\\0\end{bmatrix} = [n = 0]\) .

比较好考虑组合意义,一种情况是新开一个轮换,另一种是选一个轮换插入 . 注意插入位置不同形成的轮换不同,共有 \(n - 1\) 个位置可以插入 .

似乎没有实用的通项公式 .

第二类斯特林数

定义

「第二类斯特林数(斯特林子集数)」记作 \(\begin{Bmatrix}n\\k\end{Bmatrix}\)\(S(n, k)\),表示将两两不同的 \(n\) 个元素划分为 \(k\) 个互不区分的子集的方案数 .

递推式

\[\begin{Bmatrix}n\\k\end{Bmatrix} = \begin{Bmatrix}n - 1\\k - 1\end{Bmatrix} + k\begin{Bmatrix}n - 1\\k\end{Bmatrix} \]

特别的,\(\begin{Bmatrix}n\\0\end{Bmatrix} = [n = 0]\) .

组合意义两种情况和第一类斯特林数一样,但是子集不区分顺序,因此第二种情况共有 \(k\) 种插入方式 .

通项公式

\[\begin{Bmatrix}n\\k\end{Bmatrix} = \sum_{i = 0}^{k}\frac{(-1)^{k - i}i^n}{i!(k - i)!} \]

证明考虑容斥:\(F(i)\) 表示将两两不同的 \(n\) 个元素划分为 \(i\)互相区分的集合(不允许空集)的方案数,\(G(i)\) 表示将两两不同的 \(n\) 个元素划分为 \(i\)互相区分的集合(允许空集)的方案数 .

显然有:

\[G(i) = i^n = \sum_{j = 0}^{i}\dbinom{i}{j}F(j) \]

第二种表达方式是枚举非空集个数 .

使用二项式反演:

\[\begin{aligned} F(i) &= \sum_{j = 0}^{i}(-1)^{i - j}\dbinom{i}{j}G(j)\\ &= \sum_{j = 0}^{i}(-1)^{i - j}\dbinom{i}{j}j^n\\ &= \sum_{j = 0}^{i}\frac{i!(-1)^{i - j}j^n}{j!(i - j)!}\\ \end{aligned} \]

\(F(k)\) 划分出的集合的顺序去掉即可得到 \(\begin{Bmatrix}n\\k\end{Bmatrix}\)

\[\begin{Bmatrix}n\\k\end{Bmatrix} = \frac{F(k)}{k!} = \sum_{j = 0}^{i}\frac{ (-1)^{i - j}j^n}{j!(i - j)!} \]

应用:普通幂、下降幂与上升幂互相转化

一个很奇怪的事情是网上的证明很少,于是我贺了具体数学 .

记上升阶乘幂 \(x^{\overline{n}}=\prod_{k=0}^{n-1}(x+k)\),下降阶乘幂 \(x^{\underline{n}}=\prod_{k=0}^{n-1}(x-k)\) .

首先有公式「普通幂转下降幂」:

\[x^n=\sum_{k} \begin{Bmatrix}n\\ k\end{Bmatrix} x^{\underline{k}} \]

考虑使用数学归纳法证明 . 我们由 \(x^{\underline{k + 1}} = x^{\underline{k}}(x - k)\) 可推出 \(x\cdot x^{\underline{k}} = x^{\underline{k + 1}} + kx^k\),那么:

\[\begin{aligned} x\cdot x^{n - 1} &= x\sum_{k}\begin{Bmatrix}n - 1\\ k\end{Bmatrix}x^{\underline{k}}\\ &= \sum_{k}\begin{Bmatrix}n - 1\\ k\end{Bmatrix}x^{\underline{k + 1}} + \sum_{k}\begin{Bmatrix}n - 1\\ k\end{Bmatrix}kx^{\underline{k}}\\ &= \sum_{k}\begin{Bmatrix}n - 1\\ k - 1\end{Bmatrix}x^{\underline{k}} + \sum_{k}\begin{Bmatrix}n - 1\\ k\end{Bmatrix}kx^{\underline{k}}\\ &= \sum_{k}\left(k\begin{Bmatrix}n - 1\\ k\end{Bmatrix} + \begin{Bmatrix}n - 1\\ k - 1\end{Bmatrix}\right)x^{\underline{k}}\\ &= \sum_{k}\begin{Bmatrix}n\\ k\end{Bmatrix}x^{\underline{k}}\\ \end{aligned} \]

使用类似的方法即可获得公式「上升幂转普通幂」:

\[x^{\overline{n}} = \sum_{k}\begin{bmatrix}n\\ k\end{bmatrix}x^k \]

接下来考虑如何倒过来转化,即「普通幂转上升幂」和「下降幂转普通幂」 .

观察发现,如果我们找到了上升幂与下降幂之间的关系,带入「普通幂转下降幂」的式子就可以获得「普通幂转上升幂」,另一个同理 .

这个关系并不难找:

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

然后对「普通幂转下降幂」进行变形再代入:

\[\begin{aligned} (-x)^n &= \sum_{k}\begin{Bmatrix}n\\ k\end{Bmatrix} (-x)^{\underline{k}}\\ (-1)^{n}x^n &= \sum_{k}\begin{Bmatrix}n\\ k\end{Bmatrix}(-1)^k(-x)^{\overline{k}}\\ \end{aligned} \]

得到「普通幂转上升幂」:

\[x^n = \sum_{k}\begin{Bmatrix}n\\ k\end{Bmatrix}(-1)^{n-k}x^{\overline{k}} \]

同理得到「下降幂转普通幂」:

\[x^{\underline{n}}=\sum_{k} \begin{bmatrix}n\\ k\end{bmatrix} (-1)^{n-k} x^k \]

其实这是符合斯特林反演的,所以你会斯特林反演的话也能得出后面两个式子 .

我懒得证了 . 挂个链接 .

Min-max 容斥

\(S\subseteq T\),则不难发现有 \(\left|S\cup T\right| = \max\{\left|S\right|, \left|T\right|\}\)\(\left|S\cap T\right| = \min\{\left|S\right|, \left|T\right|\}\) .

利用这一性质即可利用容斥公式,通过集合内的一个最值求出另一最值:

\[\begin{aligned} \min_{x\in S}x &= \sum_{T\subseteq S,T\neq\varnothing}(-1)^{\left|T\right| - 1}\max_{x\in T} x\\ \max_{x\in S}x &= \sum_{T\subseteq S,T\neq\varnothing}(-1)^{\left|T\right| - 1}\min_{x\in T} x\\ \end{aligned} \]

看起来挺没用的 .

比较强的是根据期望线性性有下面这条式子:

\[\begin{aligned} E\left(\min_{x\in S}x\right) &= \sum_{T\subseteq S,T\neq\varnothing}(-1)^{\left|T\right| - 1}E\left(\max_{x\in T} x\right)\\ E\left(\max_{x\in S}x\right) &= \sum_{T\subseteq S,T\neq\varnothing}(-1)^{\left|T\right| - 1}E\left(\min_{x\in T} x\right)\\ \end{aligned} \]

这个相当有用,因为有时候一个最值的期望远没有另一种好求 .

另外还可以扩展到 \(\gcd\)\(\operatorname{lcm}\)

\[\mathop{\operatorname{lcm}}\limits_{x\in S}x = \prod_{T\subseteq S,T\neq\varnothing}\left(\gcd_{x\in T} x\right)^{(-1)^{\left|T\right| - 1}} \]

虽然我很没用,但看到几位这么有用,真好!

例题

积木

\(n\) 堆积木,每堆有 \(a_i\) 个蓝色积木,\(b_i\) 个绿色积木,\(c_i\) 个红色积木 . 每次任选两堆积木,用完这两堆之间的所有积木 建出一栋楼,求总方案数 .

两个方案不同,当且仅当选取的积木堆不同或建成高楼的某一层颜色不同 .

\(1\le n\le 2\times 10^5, 0\le a_i, b_i, c_i\le 150\) .

固定两堆积木,方案数为 $\dbinom{a_i + a_j + b_i + b_j + c_i + c_j}{a_i + a_j, b_i + b_j, c_i + c_j} $ .

发现是一个三维格路计数的形式,值域不大故使用 DP 求解 .

已经没有什么好害怕的了

[JLOI2016] 成绩比较

看到这个「恰好」就比较套路的放上二项式反演:设 \(f(k)\) 表示恰好 \(k\) 个人被碾压,\(g(x)\) 表示钦定 \(k\) 个人被碾压 .

不难得到反演式子:

\[g(k) = \sum_{i = k}^{n}\dbinom{i}{k}f(i)\Leftrightarrow f(k) = \sum_{i = k}^{n}(-1)^{i - k}\dbinom{i}{k}g(i) \]

考虑求 \(g(k)\),有式子:

\[g(k) = \dbinom{n - 1}{k}\prod_{i = 1}^{m}\sum_{s = 1}^{U_i}\dbinom{n - k - 1}{R_i - 1}s^{n - R_i}(U_i - s)^{R_i - 1} \]

简单解释:选出 \(k\) 个人被钦定,对于每一科考虑枚举 D 神的分数,在没被钦定的 \(n - k - 1\) 个人中选出 \(R_i - 1\) 个人作为分数比 D 神高的人,然后可以知道每个人分数的可能数,其积为每个人的分数的总可能数 .

这样复杂度是基于值域的,考虑展开后面的依托:

\[\begin{aligned} &\sum_{s = 1}^{U_i}\dbinom{n - k - 1}{R_i - 1}s^{n - R_i}(U_i - s)^{R_i - 1}\\ =&\sum_{s = 1}^{U_i}\dbinom{n - k - 1}{R_i - 1}s^{n - R_i}\sum_{j = 0}^{R_i - 1}\dbinom{R_i - 1}{j}U_i^{j}(-1)^{R_i - 1 - j}s^{R_i - 1 - j}\\ =&\dbinom{n - k - 1}{R_i - 1}\sum_{j = 0}^{R_i - 1}(-1)^{R_i - 1 - j}\dbinom{R_i - 1}{j}U_i^{j}\sum_{s = 1}^{U_i}s^{n - j - 1}\\ =&\dbinom{n - k - 1}{R_i - 1}h(i) \end{aligned} \]

这个 \(h(i)\) 部分只与 \(i\) 有关所以单独提出来进行预处理,现在和值域有关的部分只剩下了后面的自然数幂和,这样就可以拉插或伯努利数处理了 .

但是我不会拉插也不会伯努利数,咋整呀?

答案是用扰动法可以得到自然数幂和的一个递推式:

\[S_{t}(n) = \sum_{k = 1}^{n}k^{t} = \frac{(n + 1) ^ {t + 1} - \sum_{j = 0}^{t - 1}\dbinom{t + 1}{j}S_j(n)}{(t + 1)} \]

我写这个是为了让你知道我代码里有啥,最好还是用拉插的,不然别人也不知道你在干什么 .

这样可以 \(O(mR^2) = O(n^3)\) 预处理出所有的 \(h(i)\),然后把它带回原式:

\[f(k) = \sum_{i = k}^{n}(-1)^{i - k}\dbinom{i}{k}\dbinom{n - 1}{i}\prod_{j = 1}^{m}\dbinom{n - i - 1}{R_j - 1}h(j) \]

可以 \(O(n^2)\) 算出 .

[TJOI2018] 教科书般的亵渎

\(x\) 段贡献是:

\[\sum_{i = 1}^{mx - a_x}i^k - \sum_{i = x}^{m}(a_i - a_x)^k \]

后一半暴力算,前一半是个经典的自然数幂和 .

当然可以插出来不过放在斯特林数还是要尊重一下:

\[\begin{aligned} \sum_{i = 1}^{n}i^k &= \sum_{i = 1}^{n}\sum_{j = 1}^{k}\begin{Bmatrix}k\\ j\end{Bmatrix}i^{\underline{j}}\\ &= \sum_{i = 1}^{n}\sum_{j = 1}^{k}\begin{Bmatrix}k\\ j\end{Bmatrix}\dbinom{i}{j}j!\\ &= \sum_{j = 1}^{k}\begin{Bmatrix}k\\ j\end{Bmatrix}j!\sum_{i = 1}^{n}\dbinom{i}{j}\\ &= \sum_{j = 1}^{k}\begin{Bmatrix}k\\ j\end{Bmatrix}j!\dbinom{n + 1}{j + 1}\\ &= \sum_{j = 1}^{k}\begin{Bmatrix}k\\ j\end{Bmatrix}j!\frac{(n + 1)^{\underline{j + 1}}}{(j + 1)!}\\ \end{aligned} \]

斯特林数直接 \(O(k^2)\) 预处理,后面下降幂由于 \(j\) 不大直接暴力计算 .

Crash 的文明世界

考虑使用斯特林数将普通幂转化为下降幂,进一步转为组合数 .

\[\begin{aligned} S(u) &= \sum_{v = 1}^{n}\sum_{i = 0}^{k}\begin{Bmatrix}k\\ i\end{Bmatrix}\operatorname{dis}(u, v)^{\underline{k}}\\ &= \sum_{v = 1}^{n}\sum_{i = 0}^{k}\begin{Bmatrix}k\\ i\end{Bmatrix}\dbinom{\operatorname{dis}(u, v)}{i}i!\\ &= \sum_{i = 0}^{k}\begin{Bmatrix}k\\ i\end{Bmatrix}i!\sum_{v = 1}^{n}\dbinom{\operatorname{dis}(u, v)}{i}\\ \end{aligned} \]

\(f_{u, i} = \sum_{v\in u\text{'s subtree}}\binom{\operatorname{dis}(u, v)}{i}\),有转移:

\[\begin{aligned} f_{u, i} &= \sum_{v\in u\text{'s son}}\sum_{x\in v\text{'s subtree}}\dbinom{\operatorname{dis}(v, x) + 1}{i}\\ &= \sum_{v\in u\text{'s son}}\sum_{x\in v\text{'s subtree}}\dbinom{\operatorname{dis}(v, x)}{i} + \dbinom{\operatorname{dis}(v, x)}{i - 1}\\ &= \sum_{v\in u\text{'s son}}f_{v, i} + f_{v, i - 1}\\ \end{aligned} \]

然后换个根就做完了 .