前置知识
二项式定理:(a+b)n=∑ni=0(ni)aibn−i。
二项式反演
反演公式1:
f(n)=n∑i=0(ni)g(i)⟺g(n)=n∑i=0(−1)n−i(ni)f(i)
证明:
n∑i=0(−1)n−i(ni)f(i)=n∑i=0(−1)n−i(ni)i∑j=0(ij)g(j)=n∑j=0g(j)n∑i=j(−1)n−i(ni)(ij)
然后我们需要应用到组合数的一个结论:
(ni)(ij)=(nj)(n−ji−j)
尝试用组合意义理解:我们要在 n 个数中选一个 i 元子集 A,再选一个属于 A 的 j 元子集 B,左边就是先选 A 再选 B,右边是先选 B 再选 A,所以两者相等。
所以:
n∑j=0g(j)n∑i=j(−1)n−i(ni)(ij)=n∑j=0g(j)n∑i=j(−1)n−i(nj)(n−ji−j)=n∑j=0g(j)(nj)n∑i=j(−1)n−i(n−ji−j)=n∑j=0g(j)(nj)n−j∑i=0(−1)n−(i+j)(n−j(i+j)−j)=n∑j=0g(j)(nj)n−j∑i=0(−1)(n−j)−i(n−ji)=n∑j=0g(j)(nj)(1−1)n−j=g(n)
得证。
反演公式2:
f(n)=n∑i=0(ni)(−1)ig(n)⟺g(n)=n∑i=0(ni)(−1)if(n)
反演公式3:
f(k)=n∑i=k(ik)g(i)⟺g(k)=n∑i=k(−1)i−k(ik)f(i)
应用
关键:要求 g(n),尝试找到 f(n)=∑ni=0(ni)g(i) 且 f(n) 便于计算,然后用反演求出 g(n)。
题目一般会要求类似满足恰好 k 个性质的方案的个数,这个时候就很适合用二项式反演。
求错排
思路:
这个经典问题可以用二项式反演来做。
我们让 fn=n!,Dn 表示错排数。
则会有:
fn=n∑i=0(ni)Di
还是组合意义来理解,每个排列都有若干个位置满足 pi=i,我们先枚举有多少个位置,再枚举哪些位置,剩下的必然是错排了。
于是我们可以直接二项式反演:
Dn=n∑i=0(−1)n−i(ni)fi=n∑i=0(−1)n−in!i!(n−i)!i!=n∑i=0(−1)n−in!(n−i)!=n!n∑i=0(−1)n−i(n−i)!=n!n∑i=0(−1)ii!
染色
有 n 个格子排成一行,需要用 k 种颜色染色,要求两两不同色且每种颜色至少出现一次。求方案数。
思路:
我们设 fk 表示用 k 种颜色染色两两不同色,但是不要求每种颜色至少出现一次。
再设 gk 表示表示用 k 种颜色染色两两不同色,要求每种颜色至少出现一次。
于是我们有:
fk=k∑i=0(ki)gi
如何理解?首先对于任何一种染色方案,我们必然是选取了 k 颜色的一个子集去染,枚举选了哪些子集即可。
至于 fk,这其实是 HNOI越狱 这题,我们可以知道 fk=k(k−1)n−1,于是:
gk=k∑i=0(−1)k−i(ki)i(i−1)n−1
然后就做完了。
求第二类斯特林数。
思路:
首先假设盒子有区别。
同理,fk 表示盒子可以为空,gk 表示盒子不能为空,可以得到:
fk=k∑i=0(ki)gi
又由于 fk=km,所以反演一下就能得到答案。
用二项式反演转化成至少 k 个,显然答案是 (nk)22n−k,注意对指数取模要用模数减一。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下