容斥原理是组合数学中一种非常重要的思想。
容斥通式:
设全集为 U 共包含 n 种不同的属性,第 i 种属性为 Pi ,拥有 Pi 的元素组成的集合为 Si 。
集合的并集:
∣i=1⋃nSi∣=m=1∑n(−1)m−1ai<ai+1∑∣i=1⋂mSai∣
集合的交集:
∣i=1⋂nSi∣=∣U∣−∣i=1⋃nSi∣=∣U∣−m=1∑n(−1)m−1ai<ai+1∑∣i=1⋂nSai∣
其中 Si 表示 Si 的补集。
容斥的性质
简单来说,容斥一共有几个要素
- 物品 q(S) 表示至少满足属性集合 S 的物品个数。
- 贡献函数 g(k) 表示对于一个有 k 个属性的物品,对答案的贡献。
- 容斥系数 f(x) 表示大小为 x 的集合对答案的贡献。
一般来讲,一个有 n 个属性的物品对答案的贡献为:
g(n)=i=1∑n(in)f(i)
大多数情况下,g(n)=1 ,即一个物品对答案的贡献一般为 1 。这个时候容斥系数 f(i)=(−1)i+1 。
总的答案为
Ans=S⊆U∑=q(S)f(∣S∣)
求容斥系数
已知g(n)=∑i=0n(in)f(i),求 f(x) 。
首先可以递推求,假设已知 f(1) 到 f(n) ,求 f(n+1) 。整个过程下来时间复杂度 O(n2) 。
g(n+1=)=i=0∑n+1(in+1)f(i)f(n+1)=g(n+1)−i=0∑n(in+1)f(i)
也可以用多项式去求,时间复杂度 O(nlogn) 。
g(n)=i=0∑n(n−i)!n!i!f(i)=n!i=0∑n(n−i)!1i!f(i)n!g(n)=i=0∑n(n−i)!1i!f(i)
接下来生成函数,
n!g(n) 的生成函数 G(x)=∑i=0∞xii!g(i),
(n−i)!1 即 i!1 (因为 ∑i=1n(n−i)!1 所以可以直接替换)的生成函数H(x)=∑i=0∞xii!1=ex,
i!f(i) 的生成函数 F(x)=∑i=0∞xii!f(i) 。
则 G(x)=H(x)F(x) 。
所以 F(x)=e−xG(x) 。套个多项式求逆就行。
容斥原理常见问题模型
不定方程非负整数解计数
简单版:给定 k 个未知数 x1,x2,⋯,xk 和一个方程 x1+x2+⋯+xk=r ,求方程非负整数解的个数。
对于这个问题可以直接转换成向 k 个盒子里放 r 个球,可空的方案数。然后在每个盒子里先补上一个球,变成 k 个盒子里放 r+k 个球,不可空的方案数。
然后插板法,在 r+k−1 个球之间的空隙里插入 k−1 个板。总的答案 (k−1r+k−1) 。
升级版:给定 k 个未知数 x1,x2,⋯,xk ,k 个约束条件分别为 xk≤nk 和一个方程 x1+x2+⋯+xk=r ,求方程非负整数解的个数。
这是一个求交集的问题,容斥是用来求并集的,所以可以转化为先求所有不满足条件的情况,再用上面算出来的总情况做差。
对于每个未知数 xi ,保证 xi 不满足要求的办法就是用 xi′=xi+ni+1 替换 xi 。所以对于任意一个集合 S 表示集合中的元素全部不符合条件,则
q(S)=(k−1r+k−1−∑i∈s(ni+1))
容斥系数 f(∣S∣) 很简单,就是 (−1)∣S∣ 。
所以答案为
ans=S⊆U∑f(∣S∣)q(S)=s⊆U∑(−1)∣S∣(k−1r+k−1−∑i∈s(ni+1))
注意这里虽然没有用全集相减,但由于 ∅⊆U 即所有数都至少有零个不合法也算在内,所以计算出来的答案是正确的。
错排计数
求一个长度为 n 的排列中,满足 ai=i 的方案数
可以通过枚举哪些位置冲突,即 ai=i 来进行容斥。对于每个大小为 ∣S∣ 集合 Si 表示至少有 ∣S∣ 个位置满足 ai=i ,即 ∀i∈S, ai=i。对于每个集合 Si 可以发现统计答案时只关心它的大小,而不关心它的具体情况,所以可以设 i=∣S∣ ,将所有满足这个条件的集合合并。满足 S 的方案数共有 q(S)=(∣S∣n) 个,这些位置选定后剩下位置的方案数为 (n−∣S∣)! ,容斥系数为 (−1)∣S∣ ,答案则为
F(n)=S⊆U∑(−1)∣S∣(n−∣S∣)!=i=0∑n(−1)i(n−i)!(in)=(−1)n+n⋅F(n−1)
求一个长度为 n 的排列中,满足恰好 m 个 ai=i 的方案数
F(n,m)=i=0∑m(−1)i(n−i)!(im)
本文作者:CloudySky
写作时间: 2022-01-21
最后更新时间: 2022-01-21
遵循协议: BY-NC-SA