组合数学
容斥
容斥原理共有两种常用形式。
对于 \(n\) 个满足第 \(i\) 个限制条件的集合 \(A_1, A_2, \dots, A_n\),
满足至少一个限制的方案数:
满足全部限制的方案数为:
其中 \(\overline{A_i}\) 表示 \(A_i\) 的补集,即不满足限制 \(i\) 的集合。
例题
P3813 [FJOI2017] 矩阵填数
题目要求子矩阵最大值 \(=v\),即所有值 \(\le v\) 且至少一个值 \(=v\),后者是难做的。
首先需要注意到答案为:
根据公式可以知道,\(\text{Ans}\) 表示满足全部 \(n\) 条限制的方案数,\(\text{calc}(S)\) 表示对于集合 \(S\) 中的限制强制不满足,不属于 \(S\) 的限制可能满足的方案数。
强制不满足限制可以令最大值强制 \(\le v-1\),此时一定不满足限制。
如何计算 \(\text{calc}(S)\)?
我们可以确定格子 \((x,y)\) 的上线 \(lim(x,y)\),对于格子 \((x,y)\):
- 若其没有限制,即不属于任何子矩阵,则 \(lim(x,y)=m\);
- 若 \((x,y)\) 所在的子矩阵 \(i\in S\),则其最大值 \(\le v-1\),即 \(\lim(x,y)\leftarrow \min(lim(x,y),v_i-1)\);
- 否则 \((x,y)\) 需要满足限制条件,即 \(\lim(x,y)\leftarrow \min(lim(x,y),v_i)\)。
知道了每个格子的 \(lim\),则可以计算 \(\text{calc}(S)\):
\(\text{Matrix}\) 表示整个矩阵,\(\text{lim}_S(x,y)\) 表示根据集合 \(S\) 算出的 \(\text{lim}(x,y)\)。
由于本题矩阵较大,但是 \(n\) 很小,离散化矩阵即可。
我们不能遍历整个矩阵,离散化后会将矩阵分成若干个小块,小块内所有 \(\text{lim}\) 都相同,所以实际实现中:
\(K\) 表示小块总数,\(\text{lim}_{S,k}\) 表示块 \(k\) 的 \(\text{lim}\),\(siz_k\) 表示小块大小。
二项式反演
二项式反演也共有两个常用式子。
这个式子中 \(f(n)\) 表示至多选择 \(n\) 个元素的方案数,\(g(n)\) 表示恰好选择 \(n\) 个元素的方案数。
这个式子中 \(f(n)\) 表示钦定选择 \(n\) 个元素,其余随便选的方案数(这里是钦定选择,而不是通俗意义上的至少,与公式一做区分),\(g(n)\) 表示恰好选择 \(n\) 个元素的方案数。
通常题目中要求恰好,可能并不好做,可以计算出至多或至少的方案数并进行二项式反演求出答案,反之亦然。
二项式定理
标准形式:
令 \(a=1,b=x\),我们还常用这个式子:
二项式定理可以将长度为 \(n\) 的求和转化为幂运算,将(局部)时间复杂度从 \(\Theta(n)\) 降到 \(\Theta(\log n)\) 甚至 \(\Theta(1)\)。
例题
P6076 [JSOI2015] 染色问题
问题要求:
- 棋盘恰好有 \(n\) 行至少有一个小方格被染色。
- 棋盘恰好有 \(m\) 列至少有一个小方格被染色。
- 恰好有 \(C\) 种颜色都在棋盘上出现至少一次。
恰好是不好做的,将条件改为至多 \(n\) 行,至多 \(m\) 列,至多 \(C\) 种颜色,这个问题是简单的,易得方案数为 \((C+1)^{nm}\),使用二项式反演即可,得到:
实现是简单的。
P4859 已经没有什么好害怕的了
简化题意:
有两个长度为 \(n\) 的序列 \(a,b\),将 \(a,b\) 中的元素任意两两配对,求 \(a_i>b_i\) 比 \(b_i>a_i\) 恰好多 \(k\) 个的方案数。(保证 \(a,b\) 中的元素互不相同。)
设 \(a_i>b_i\) 的组数为 \(x\),则 \(b_i>a_i\) 的组数为 \(n-x\),所以:
为了方便表述并不引起歧义,以下用 \(a<b\) 或 \(a>b\) 表示配对的对。
于是问题变成恰好有 \(x\) 对 \(a>b\) 的方案数。
恰好不好做,改成至少。设 \(f(i)\) 表示钦定 \(i\) 对 \(a>b\),其余随便选的方案数,\(g(i)\) 表示恰好 \(i\) 对 \(a>b\) 的方案数(即答案)。问题转变为如何计算 \(f(i)\)。
发现 \(a,b\) 顺序对答案无影响,所以先将 \(a,b\) 按升序排序。
考虑动态规划,设 \(dp_{i,j}\) 表示考虑到 \(i\),钦定 \(j\) 对 \(a>b\) 的方案数,则:
\(cnt_i\) 表示 \(\forall1\le j\le n,b_j<a_i\) 的数量。转移式子中 \(a_i\) 要么不组成 \(a>b\) 的对,要么选择比 \(a_i\) 小的 \(b\),共有 \(cnt_i-(j-1)\) 种选择。
此时 \(f(i)\) 的计算就容易了,钦定 \(i\) 对之后,剩下的可以随意排列配对,所以:
根据二项式反演即可写出 \(g(i)\):
从而得到答案:
实现同样是简单的。
CF997C Sky Full of Stars
题目大意:
给定一个 \(n\times n\) 的网格,每个格子必须填入三种颜色之一,求至少一行或一列颜色相同的方案数,对 \(998244353\) 取模。
设 \(A_i\) 表示第 \(i\) 行的颜色相同的方案(不是方案数),\(B_i\) 表示第 \(i\) 列的颜色相同的方案。则答案为:
将 \(\left|\bigcup_{i=1}^nA_i\cup\bigcup_{j=1}^nB_j\right|\) 看作一个整体,容斥展开:
发现只有 \(|S|,|T|\) 对答案有影响,而 \(S,T\) 的具体元素对答案无影响,所以:
接下来计算 \(\text{calc}(i,j)\)。
考虑当前选了 \(i\) 行,\(j\) 列,
- \(i>0,j>0\),行列都有选择,行列交叉,所以被选中的行列形成一个连通块,这一个连通块内的格子必须颜色相同,其他格子自由填色的方案数,容易得到是 \(3\times3^{(n-i)(n-j)}=3^{(n-i)(n-j)+1}\)
- \(i>0,j=0\),仅选择了行,每行颜色需要相同,但是不同行颜色可以不同,其他格子仍然是自由填色,所以方案数为 \(3^i\times3^{(n-i)n}=3^{(n-i)n+i}\)
- \(i=0,j<0\),与上情况同理,方案数为 \(3^{(n-j)n+j}\)
所以:
这个时候答案已经可以计算了,但是由于 \(n\le10^6\),第二个式子是需要 \(\Theta(n^2)\) 求的,所以还需要优化第二个式子。
考虑第二个式子:
设 \(a=n-i,b=b-j\),则 \(i=n-a,j=n-b\),于是上式可以转化为:
这个式子中,\(a,b\) 的相关性太强,我们尽量将有关 \(a\) 的项提出来,上式可以重写为:
我们可以发现,最后的 \(\sum_{b=0}^{n-1}\binom nb(-3^a)^b\) 和二项式定理的形式很像,二项式定理中:
令 \(x=-3^a\),则:
所以式子可以继续转化为:
所以最终答案为:
实现是简单的,时间复杂度 \(\Theta(n\log p+n\log n)\),\(p=998244353\),复杂度瓶颈在预处理阶乘和逆元。

浙公网安备 33010602011771号