2024-01-07 09:36阅读: 275评论: 8推荐: 6

「学习笔记」组合计数:格路计数、二项式反演、斯特林数与 Min-max 容斥

「学习笔记」二项式反演、斯特林数、Min-max 容斥

点击查看目录

Something:

题单里的部分题目还没有写所以本文在例题方面没有施工完毕,发出来仅仅是因为这篇博太常需要翻阅但是又被积压在草稿箱底部 .

补完后会删除这段话 .

格路计数

一个比较经典的 trick .

在一个 n×m 的方格内,只能向上或向右走,求从 (0,0) 走到 (n,m) 的方案数 .

答案是 (n+mn),组合意义是 n+m 次移动中选出 n 次向上移动 .

另一种解决方式是简单 DP,fi,j=fi1,j+fi,j1 .

在求解类似 i=1nj=1m(ai+aj+bi+bjai+bi) 的问题时,如果 nm 较大但值域较小,可以考虑转化为格路计数,在所有 (ai,bi) 处初始化,使用 DP 算出所有 (aj,bj) 的值 .

板子是 AGC001E .

二项式反演

终于能填这个坑了啊 .

大量参考:link1, link2 .

形式一与形式二是更常用的形式 .

形式零

假设全集 U=A1,A2,,An 的任意 i 个元素并集、交集都相等,设 f(n) 表示任意 i 个集合的补集的交集,g(n) 表示任意 i 个集合的交集 .

特别的,f(0)=|U|g(0)=|U| .

A 补集为 Ac,有一条容斥等式:

|A1A2An|=|U|i=1n|Aic|+i=1nj=1n|AicAjc|+(1)n|A1cA2cAnc|

左边就是 g(n),右边相当于 i=0n(ni)f(i) . 即 g(n)=i=0n(1)i(ni)f(i) .

补集的补集就是原集,那么同理可得 f(n)=i=0n(1)i(ni)g(i) .

那么可以得到形式零:

f(n)=i=0n(1)i(ni)g(i)g(n)=i=0n(1)i(ni)f(i)

其他形式都可以在这个形式基础上变形得出 .

形式一

f(n)=i=0n(ni)g(i)g(n)=i=0n(1)ni(ni)f(i)

有一个组合意义:f(i) 为在一个集合中钦定 i 个元素被选择,其他元素随便选的方案数,g(i) 为在该集合中选出恰好 i 个元素的方案数 .

两个代数证明:

证明 1

h(n)=(1)ng(n),带入形式零:

f(n)=i=0n(ni)h(i)h(n)(1)n=i=0n(1)i(ni)f(i)

观察发现 (1)n+i=(1)ni,因此得出形式二:

f(n)=i=0n(ni)h(i)h(n)=i=0n(1)ni(ni)f(i)

证明 2

硬带:

f(n)=i=0n(ni)g(i)=i=0n(ni)j=0i(1)ij(ij)f(j)=i=0nj=0i(ni)(ij)(1)ijf(j)=j=0nf(j)i=jn(ni)(ij)(1)ij=j=0nf(j)i=jn(nj)(niij)(1)ij=j=0n(nj)f(j)k=0nj(nik)1njk(1)k

k=0nj(nik)1njk(1)k 这一坨,当 n=j 时等于 1,否则等于 (11)nj=0 .

带回:

f(n)=j=0n(nj)f(j)k=0nj(nik)1njk(1)k=j=0n(nj)f(j)[n=j]=(nn)f(n)=f(n)

形式二

f(n)=i=nm(1)i(in)g(i)g(n)=i=nm(1)i(in)f(i)

证明考虑直接代入:

f(n)=i=nm(1)i(in)g(i)=i=nm(1)i(in)j=im(1)j(ji)f(j)=j=nmf(j)i=nj(in)(ji)(1)i+j=j=nmf(j)i=nj(jn)(jnin)(1)2j+(ij)=j=im(jn)f(j)k=0jn(jnk)(1)k=j=nm(jn)f(j)[j=n]=(nn)f(n)=f(n)

形式三

f(n)=i=nm(in)g(i)g(n)=i=nm(1)in(in)f(i)

证明与形式一比较类似:

f(n)=i=nm(in)g(i)=i=nm(in)j=im(1)ji(ji)f(j)=j=nmf(j)i=nj(ji)(in)(1)ji=j=nm(jn)f(j)i=nj(jnji)(1)ji=j=nm(jn)f(j)k=0jn(jnk)1jnk(1)k=j=nm(jn)f(j)[n=j]=(nn)f(n)=f(n)

斯特林数

第一类斯特林数

定义

「第一类斯特林数(斯特林轮换数)」记作 [nk]s(n,k),表示将两两不同的 n 个元素划分为 k 个互不区分的轮换的方案数 .

「轮换」指的是一个首尾相接的序列,例如说 [A,B,C,D]=[B,C,D,A]=[C,D,A,B]=[D,A,B,C],但是 [A,B,C,D][D,C,B,A] .

递推式

[nk]=[n1k1]+(n1)[n1k]

特别的,[n0]=[n=0] .

比较好考虑组合意义,一种情况是新开一个轮换,另一种是选一个轮换插入 . 注意插入位置不同形成的轮换不同,共有 n1 个位置可以插入 .

似乎没有实用的通项公式 .

第二类斯特林数

定义

「第二类斯特林数(斯特林子集数)」记作 {nk}S(n,k),表示将两两不同的 n 个元素划分为 k 个互不区分的子集的方案数 .

递推式

{nk}={n1k1}+k{n1k}

特别的,{n0}=[n=0] .

组合意义两种情况和第一类斯特林数一样,但是子集不区分顺序,因此第二种情况共有 k 种插入方式 .

通项公式

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

证明考虑容斥:F(i) 表示将两两不同的 n 个元素划分为 i互相区分的集合(不允许空集)的方案数,G(i) 表示将两两不同的 n 个元素划分为 i互相区分的集合(允许空集)的方案数 .

显然有:

G(i)=in=j=0i(ij)F(j)

第二种表达方式是枚举非空集个数 .

使用二项式反演:

F(i)=j=0i(1)ij(ij)G(j)=j=0i(1)ij(ij)jn=j=0ii!(1)ijjnj!(ij)!

F(k) 划分出的集合的顺序去掉即可得到 {nk}

{nk}=F(k)k!=j=0i(1)ijjnj!(ij)!

应用:普通幂、下降幂与上升幂互相转化

一个很奇怪的事情是网上的证明很少,于是我贺了具体数学 .

记上升阶乘幂 xn¯=k=0n1(x+k),下降阶乘幂 xn_=k=0n1(xk) .

首先有公式「普通幂转下降幂」:

xn=k{nk}xk_

考虑使用数学归纳法证明 . 我们由 xk+1_=xk_(xk) 可推出 xxk_=xk+1_+kxk,那么:

xxn1=xk{n1k}xk_=k{n1k}xk+1_+k{n1k}kxk_=k{n1k1}xk_+k{n1k}kxk_=k(k{n1k}+{n1k1})xk_=k{nk}xk_

使用类似的方法即可获得公式「上升幂转普通幂」:

xn¯=k[nk]xk

接下来考虑如何倒过来转化,即「普通幂转上升幂」和「下降幂转普通幂」 .

观察发现,如果我们找到了上升幂与下降幂之间的关系,带入「普通幂转下降幂」的式子就可以获得「普通幂转上升幂」,另一个同理 .

这个关系并不难找:

xn_=(1)n(x)n¯

然后对「普通幂转下降幂」进行变形再代入:

(x)n=k{nk}(x)k_(1)nxn=k{nk}(1)k(x)k¯

得到「普通幂转上升幂」:

xn=k{nk}(1)nkxk¯

同理得到「下降幂转普通幂」:

xn_=k[nk](1)nkxk

其实这是符合斯特林反演的,所以你会斯特林反演的话也能得出后面两个式子 .

我懒得证了 . 挂个链接 .

Min-max 容斥

ST,则不难发现有 |ST|=max{|S|,|T|}|ST|=min{|S|,|T|} .

利用这一性质即可利用容斥公式,通过集合内的一个最值求出另一最值:

minxSx=TS,T(1)|T|1maxxTxmaxxSx=TS,T(1)|T|1minxTx

看起来挺没用的 .

比较强的是根据期望线性性有下面这条式子:

E(minxSx)=TS,T(1)|T|1E(maxxTx)E(maxxSx)=TS,T(1)|T|1E(minxTx)

这个相当有用,因为有时候一个最值的期望远没有另一种好求 .

另外还可以扩展到 gcdlcm

lcmxSx=TS,T(gcdxTx)(1)|T|1

虽然我很没用,但看到几位这么有用,真好!

例题

积木

n 堆积木,每堆有 ai 个蓝色积木,bi 个绿色积木,ci 个红色积木 . 每次任选两堆积木,用完这两堆之间的所有积木 建出一栋楼,求总方案数 .

两个方案不同,当且仅当选取的积木堆不同或建成高楼的某一层颜色不同 .

1n2×105,0ai,bi,ci150 .

固定两堆积木,方案数为 (ai+aj+bi+bj+ci+cjai+aj,bi+bj,ci+cj) .

发现是一个三维格路计数的形式,值域不大故使用 DP 求解 .

已经没有什么好害怕的了

ab 进行排序,使得处理大小时可以直接从前缀和后缀转移过来 .

Fi,j 表示前 iai 中,有多少种方案钦定配对了 j 个满足 a>b 的二元组,有转移:

Fi,j=Fi1,j+(pi(j1))Fi1,j1

其中 pi 满足 bpi<ai<bpi+1 .

对于状态中没有进行配对的,令它们肆意配队,为了更方便形式化 f(i)=(ni)!Fn,i 表示整个序列钦定 j 个满足 a>b 的二元组的方案数 .

g(n) 表示序列中存在恰好 j 个满足 a>b 的二元组的方案数,二项式反演:

f(k)=i=kn(ik)g(i)g(k)=i=kn(1)ik(ik)f(i)

答案即为 g(n+k2) .

[JLOI2016] 成绩比较

看到这个「恰好」就比较套路的放上二项式反演:设 f(k) 表示恰好 k 个人被碾压,g(x) 表示钦定 k 个人被碾压 .

不难得到反演式子:

g(k)=i=kn(ik)f(i)f(k)=i=kn(1)ik(ik)g(i)

考虑求 g(k),有式子:

g(k)=(n1k)i=1ms=1Ui(nk1Ri1)snRi(Uis)Ri1

简单解释:选出 k 个人被钦定,对于每一科考虑枚举 D 神的分数,在没被钦定的 nk1 个人中选出 Ri1 个人作为分数比 D 神高的人,然后可以知道每个人分数的可能数,其积为每个人的分数的总可能数 .

这样复杂度是基于值域的,考虑展开后面的依托:

s=1Ui(nk1Ri1)snRi(Uis)Ri1=s=1Ui(nk1Ri1)snRij=0Ri1(Ri1j)Uij(1)Ri1jsRi1j=(nk1Ri1)j=0Ri1(1)Ri1j(Ri1j)Uijs=1Uisnj1=(nk1Ri1)h(i)

这个 h(i) 部分只与 i 有关所以单独提出来进行预处理,现在和值域有关的部分只剩下了后面的自然数幂和,这样就可以拉插或伯努利数处理了 .

但是我不会拉插也不会伯努利数,咋整呀?

答案是用扰动法可以得到自然数幂和的一个递推式:

St(n)=k=1nkt=(n+1)t+1j=0t1(t+1j)Sj(n)(t+1)

我写这个是为了让你知道我代码里有啥,最好还是用拉插的,不然别人也不知道你在干什么 .

这样可以 O(mR2)=O(n3) 预处理出所有的 h(i),然后把它带回原式:

f(k)=i=kn(1)ik(ik)(n1i)j=1m(ni1Rj1)h(j)

可以 O(n2) 算出 .

[TJOI2018] 教科书般的亵渎

x 段贡献是:

i=1mxaxiki=xm(aiax)k

后一半暴力算,前一半是个经典的自然数幂和 .

当然可以插出来不过放在斯特林数还是要尊重一下:

i=1nik=i=1nj=1k{kj}ij_=i=1nj=1k{kj}(ij)j!=j=1k{kj}j!i=1n(ij)=j=1k{kj}j!(n+1j+1)=j=1k{kj}j!(n+1)j+1_(j+1)!

斯特林数直接 O(k2) 预处理,后面下降幂由于 j 不大直接暴力计算 .

Crash 的文明世界

考虑使用斯特林数将普通幂转化为下降幂,进一步转为组合数 .

S(u)=v=1ni=0k{ki}dis(u,v)k_=v=1ni=0k{ki}(dis(u,v)i)i!=i=0k{ki}i!v=1n(dis(u,v)i)

fu,i=vu's subtree(dis(u,v)i),有转移:

fu,i=vu's sonxv's subtree(dis(v,x)+1i)=vu's sonxv's subtree(dis(v,x)i)+(dis(v,x)i1)=vu's sonfv,i+fv,i1

然后换个根就做完了 .

本文作者:K8He

本文链接:https://www.cnblogs.com/K8He/p/BinomialInversion_Stirling_And_Min-max.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   K8He  阅读(275)  评论(8编辑  收藏  举报
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示