二项式反演入门

对于序列 {fn}{gn},通过 f 计算出 g 叫做正演,通过 g 计算出 f 叫做反演。

形式#

二项式反演讲的是:

gn=i=0n(ni)fifn=i=0n(1)ni(ni)gi

证明#

将组合数展开得到:

gn=i=0n(ni)fign=i=0nn!i!(ni)!fignn!=i=0n1(ni)!fii!

考虑序列 {fn}{gn} 的指数生成函数 F(x),G(x)。上式是一个卷积的形式,写成指数生成函数就是 G(x)=exF(x)F(x)=1exG(x)

exx=0 处泰勒展开得到 ex=i=0n(1)ixii!,和 G(x) 卷起来得到

F(x)=k=0ni=0k(1)ki1(ki)!gii!xkfnn!=i=0n(1)ni1(ni)!gii!fn=i=0n(1)nin!i!(ni)!gi=i=0n(1)ni(ni)gi

证毕。

应用#

错位排序#

求满足 aii[1,n] 的排列数。

D(n) 表示长度为 n 的序列的错排数,通过枚举错排位置可得:

n!=i=0n(ni)D(i)

显然可以二项式反演,得到:

D(n)=i=0n(1)ni(ni)i!=i=0n(1)nin!i!(ni)!i!=i=0n(1)nin!(ni)!=n!i=0n(1)i1i!

第二类斯特林数#

第二类斯特林数 {nk},表示将 n 个互不相同的元素分成 k 个互不区分的非空子集的方案数。

  • 注意到这里元素互不相同,所以不可以直接插板!
  • 以下内容可以直接使用容斥原理直接得出。

定义 gn 表示允许空集的方案数,fn 为不允许空集的方案数(此处集合互相区分),显然,每个数都有 k 种选择,共 kn 种。

枚举 k 个集合中的空集,剩下的非空,加起来得到 gn,即:

gk=i=0k(ki)fki

对其进行二项式反演,得到:

fk=i=0k(1)ki(ki)gi=i=0k(1)kik!i!(ki)!in

由于这里 fn 集合是相互区分开的,我们最后要除去集合间的排列,得到

{nk}=fkk!=i=0k(1)kiini!(ki)!=i=0k(1)ki(ki)!ini!

注意到这里还是个卷积,可以跑多项式 O(nlogn) 求。

将这个式子带回,得到

gk=kn=i=0kk!i!(ki)!{nk}i!=i=0kPnk{nk}

posted @   LewisLi  阅读(186)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩