从 简单容斥 到 min-max 容斥 与 二项式反演

证明基本都是自己瞎证的,如果证法比较丑请见谅。

容斥原理

一道小学题n(n109) 以内不能被 2,3,5 整除的整数个数。

VCSXLQ@HL_N79HFO_3V8CSF.png

考虑这个 Venn 图。三个圆分别表示被 2,3,5 整除的数构成的集合,那么要求的就是圆外的面积。

假设什么限制也不管,只管一共有 n 个数,那么每块都是算一遍。

圆外的面积自然就是总面积减去里面的,我们想到 nn2n3n5

你发现重合的部分多扣了,所以你又把两两的重合部分加上,现在你的答案是 nn2n3n5+n2×3+n2×5+n3×5

你发现中间(三圆重合的部分)又多出来了,把它减掉。nn2n3n5+n2×3+n2×5+n3×5n2×3×5

你发现它完美了:该算的被算了一遍,别的被算了零遍。


考虑一个比较一般的容斥的式子:

A1Ann 个集合,U={1,2,,n}。那么

|i=1nAi|=SU,S(1)|S|1|iSAi|

为什么这是对的?

考虑一个元素。假设它出现在了 n 个集合中的 k(k>0) 个。则它的贡献恰好是
i=1k(1)i1(ki)=1i=0k(1)i(ki)=1(1+1)k=1
。我们发现有出现过的算了一次,没出现过的算了零次。

根据上面的经验,我们发现,容斥就是通过加加减减的方式,使得符合要求的方案算到恰好一遍,其他方案算到零遍,以做到不重不漏不多不少。

二项式反演

小学题加强版k=0,1,2,3,分别求出 n(n109) 以内恰能被 2,3,5 中的 k 个整除的整数个数。

先考虑 k=3,这时候答案显然是三圆重合的部分,就是 f3=n2×3×5

然后是 k=2,这时我们想到 n2×3+n2×5+n3×5。但是你发现中间那块被多算了 3 遍,于是有 f2=n2×3+n2×5+n3×5(32)f3 了。

接下来算 k=1,和刚才一样,你算出了 f1=n2+n3+n5(21)f2(31)f3

那么 f0=n(10)f1(20)f2(30)f3


考虑比较一般的问题。你有 n 个限制,对所有的 k,要求出满足恰好 k 个限制的方案数。

对于一个 k,你强行钦定它满足其中 k 个条件,而算出答案为 gk;记最后的答案为 fk。那么根据刚才的经验,很明显:

fk=gkj=k+1n(jk)fj

但这个复杂度是 n2 的,有时候 n 很大,你算不了。有没有更快的做法?

那你移个项,容易得到:gk=j=kn(jk)fj

组合数拆出来:k!gk=j=kn1(jk)!j!fj

gk=gnk(nk)!,fk=fnk(nk)!。那么 gk=j=0k1(kj)!fj

然后是喜闻乐见的生成函数环节。G1(x)=igixi,F1(x)=ifixi

那么就有 G1(x)=exF1(x)。所以 F1(x)=exG1(x)。而 ex=i(1)ixii!

这时候我们就有了明显的思路:先从 g 数组转成 G1(x),然后使用 FFT/NTT 做卷积,算出 F1(x),然后转成 f 数组。

时间复杂度 O(nlogn)


但是有时候我们不仅想这样求,还想把式子给他写得漂亮些。

刚刚我们推到了 F1(x)=exG1(x),其中 ex=i(1)ixii!

也就是 fk=j=0k(1)kj(kj)!gj

k!fk=j=kn(1)jk(jk)!j!gj

fk=j=kn(jk)(1)kjgj。事实上啊,

gk=j=kn(jk)fjfk=j=kn(jk)(1)kjgj

这个式子就是二项式反演了。二项式反演还有更好看的形式:

fn=j=0n(1)j(nj)gjgn=j=0n(1)j(nj)fj

min-max 容斥

再看看这个容斥的式子:

A1Ann 个集合,U={1,2,,n}。那么|i=1nAi|=SU,S(1)|S|1|iSAi|
试试把 换成 max,把 换成 min,集合 Ai 改成数 ai 吧。那么得到:

maxi=1nai=SU,S(1)|S|1miniSai

举个例子:
max{2,3,4}=min{2}+min{3}+min{4}min{2,3}min{2,4}min{3,4}+min{2,3,4}=2+3+4223+2=4

你发现它竟然是对的!

能证明吗?

一样的思路,不妨假设 a1a2an。考虑 ax 被算到的次数,为:
i=0nx(nxi)(1)nx
(它要是子集的最小值,该子集的其他元素就只能选后面的)。

k<n 时,化为 (1+1)nk=0;当 k=n 时,化为 1

故只有最大的那个值贡献到了答案,它就是对的。这就是 min-max 容斥。

但是你觉得这个东西很蠢,最大值明明可以直接算。

之所以要拿出来说,是因为 min-max 容斥在期望下也是对的。

也就是说,

E(maxi=1nxi)=SU,S(1)|S|1E(miniSxi)

成立。


举例说明:袋子里有 n(n20) 种颜色的球,每一回合你会拿出一个球然后放回,摸出的球为第 i 种颜色的概率为 pi(pi=1)。求期望多少回合后,每种颜色都摸到过至少一次。(HDU4336)

设第 i 种颜色期望 xi 次被第一次摸到,则答案是 E(maxi=1nxi)

你发现 E(maxxi) 不好求,E(miniSxi) 还比较好求,为 1iSpi

套用刚刚的式子,就得到
E(maxi=1nxi)=SU,S(1)|S|1E(miniSxi)=SU,S(1)|S|11iSpi

n 只有 20,直接算就行了。


Wait! 但是我们还没证明 min-max 容斥在期望下也是对的呢!

考虑在这里计算期望的一种方法:

E(maxi=1nxi)=tP(x=t)maxi=1nti
E(mini=1nxi)=tP(x=t)mini=1nti

其中 t 是一个长度为 n 的序列。

E(maxi=1nxi)=tP(x=t)maxi=1nti=tP(x=t)SU,S(1)|S|1miniSti=SU,S(1)|S|1tP(x=t)miniSti=SU,S(1)|S|1E(miniSxi)

嗯,这样就证完了,也没啥意思。


还有更强的式子
U={1,2,,n}kthmaxi=1naia 数组的第 k 大值,则:

kthmaxi=1nai=SU,S(1)|S|k(|S|1k1)miniSai

(规定 n<m(nm)=0

证明:
不妨假设 a1a2an
SU,S(1)|S|k(|S|1k1)miniSai=i=1naiSU,S(1)|S|k(|S|1k1)[ai=minjSaj]=i=1naij=kn(nij1)(j1k1)(1)jk
对于组合数,有等式 (ab)(bc)=(ac)(acbc)。于是:
=i=1naij=kn(nik1)(nik+1jk)(1)jk=i=1nai(nik1)j=kn(nk+1ijk)(1)jk=i=1nai(nik1)j=0nk+1i(nk+1ij)(1)j
i=nk+1 时,(nik1)j=0nk+1i(nk+1ij)(1)j=1
否则 (nik1)j=0nk+1i(nk+1ij)(1)j=0
所以 i=1nai(nik1)j=0nk+1i(nk+1ij)(1)j=kthmaxi=1nai
于是证完了。

于是又有

E(kthmaxi=1nxi)=SU,S(1)|S|k(|S|1k1)E(miniSxi)

EXTRA

其实还有一个关于 gcdlcm 的容斥。

它长这样:lcmi=1nai=SU,S(gcdiSai)(1)|S|1

其中 U={1,2,,n}

为什么对?你考虑 ai=kpkαk

  • 取两个数的 gcd 就是每个 αmin
  • 取两个数的 lcm 就是每个 αmax
  • 两个数相乘就是 每个 α 求和;
  • 两个数相除就是 每个 α 求差。

于是那个式子就相当于对每个 α 同时搞了个 min-max 容斥,自然就是对的了。

例题

二项式反演

luogu P4859 已经没有什么好害怕的了

luogu P4491 染色

luogu P5401 珍珠

min-max 容斥

HDU 4336 Card Collector

luogu P3175 按位或

HDU4624 Endless Spin

BZOJ 4833 最小公倍佩尔数

luogu P4707 重返现世

AGC 038E Gachapon

posted on   Dreamunk  阅读(667)  评论(1编辑  收藏  举报

编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战

导航

< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示