9. 容斥与反演

9.容斥与反演

容斥原理:

|i=1nPi|=SU(1)|S|1|sSPs|

感性理解: Pi:”满足某种性质的元素的集合“;左边:具有任意一种性质的元素的并,右边:至少具备多个性质的元素。

证明:考虑一个元素 x,设其包含在 k 个集合内,那么当集合 |s|=t 时,会被算 (kt) 次,其系数为 (1)t1,整理:

i=1k(1)i1(ki)=i=0k(ki)(1)i+1=(11)k+1=1

不定方程计数

有不定方程 xi=S,均为非负整数,有限制 xik,求解数。n,k105

  • 不好直接做,考虑容斥。
  • 枚举几个至少大于 kS 则变成 S(k+1)×i,问题转化为没有限制的问题,运用插板法解决。

ans=i=0n(1)i(ni)(S(k+1)i+n1n1)

多重集的错位排列

给定非排列的 ai,求有多少种改变顺序得到的 bi ,满足  biain2000

普通错排的递推式就是 D(n)=(n1)×(D(n1)+D(n2)) ,就是考虑最后一步,是交换之前的一个错排,还是之前的一个非错排。

但是错排还有容斥形式,至少一个的容斥系数就是:(固定零个)-(固定一个)+ (固定两个)-(固定三个)+(固定四个)...

即:(刚好打破 0 个限制)=(至少打破 0 个限制)-(至少打破 1 个限制) + (至少打破两个限制) - (至少打破三个限制)...

写成封闭形式,即 D(n)=((ni)(1)i×(ni)!)

回顾一下容斥原理的本质:容斥系数为正的时候,是为了求出那些最后一次有机会能求出的数。

另外,对于多重集的全排列公式,即 n!n1!n2!n3!...nk!

考虑 dp ,设 f[i][j] 表示考虑了 i 个数字,j 个位置强制打破。数组值存的是 容斥系数×方案数。

枚举当前数字 i 强制打破了 k 个限制, f[i][j]=f[i1][jk]×(1)k×(siz[i]k)×1(siz[i]k)! ,和上面基本一样。

最后答案即 f[m][i]×(nj)!

[JSOI2015] 染色问题

给你一个 n×m 的网格和 c 种颜色,要求每行,每列至少染色一个,c 种颜色必须全用。n,m,c400

发现有三层限制,我们至少要容斥掉两层。

f(c)至多使用 c 种颜色的方案数,则 ans=(1)ci(ci)f(i)

再容斥一维,看哪些列全为 0

f(c)=i=0m(1)mi+1(mi)((c+1)n1)i

[ZJOI2016] 小星星

给你一个无向图,再给你一个 n 个点的树,问有多少给点重编号的方式,使得树上的边均存在于原图中。

n17,m(n2)

不容易想到 O(n33n) 的树形 DP,设 f[i][j][S] 表示将 i 重标号为 j,遍历 j 在图上连的点 y 是相连的。

转移方程:

f[u][j][S]=((u,v)T(u),(j,k)G,S\subSf[v][k][S])

考虑我们为什么要存一个子集,是为了保证重标号的结果是一个排列,也即不重不漏,怎么计数?容斥!

枚举一个 S,设 g(S) 表示只考虑 S 内的编号,也即:至多选择这些点。运用子集反演,则答案为 (1)n|S|g(S)

[TJOI2019] 唱、跳、rap和篮球

给定 a,b,c,d 个唱跳rap篮球,将他们放在长度为 n 的序列中,求有多少方案满足不存在相邻的唱跳rap篮球。相同类型彼此不区分。n1000,a,b,c,d500,a+b+c+dn。时间限制 4s

很套路的容斥,我们钦定i 个相邻的,那么答案就是 i(1)if(i)

因为 n 和种类数都较小,所以我们可以直接 dp求出 f(i):设 gi,j,c 表示前 i 种颜色放了 j 个,钦定了 c 个位置,再往里插板即可。

一个比较关键的是:钦定 i 个长度为 4 的子段的方案数是多少?答案是 (n3ii),貌似高中数学称为捆绑法(我只听过一节)?

因此答案即为 i(n3ii)(1)ig(n,j,n4c)

[AHOI2018初中组] 球球的排列

给定序列,求有多少种排列方式,使得没有相邻两个数的乘积是完全平方数。n300,ai109

首先易得关键性质:若 ab=x,bc=y 为完全平方数,则 ac 同样也是。证明:ac=xyb2 显然是整数,且是完全平方数。

于是题意可以转换为:

m 种颜色的球,第 i 种的颜色有 si 个,si=n,求同色不相邻的方案,球有编号。

真的是组合计数困难题呀,想了一天的式子,中间牵扯到多重集全排列以及交换求和顺序等等知识点。

O(n^3) dp做法:

  • f[i][]

O(n^2) 容斥做法:

  • 我们可以 钦定 对于前 i 种颜色,总共j 个相邻,当前颜色有 k 个相邻,这样的情况有多少?

  • fi 表示总共有 i 个相邻。

ans=(j=1maj!)×i=0n((ni)!×fn,i×(1)i)fi,j=k=0min(aj,j) fi1,jk×1(aik)!×(ai1k)

容斥在什么时候起效?

  • =
  • minmax
  • 至少 或 恰好

二项式反演

实际上,反演在线性代数上的本质相当于矩阵乘法,即为,有两个向量 F,G,转移矩阵 H,有

F=G×H

如果 H 存在逆 H1,则有:

G=F×H1

问题转化为了构造矩阵以及求矩阵逆元。

由此本质出发,矩阵自身进行一些转置什么的操作,依旧满足性质。

定理内容:

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

则有:

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

证明:使用vfk原ppt方法

我们依旧回到错排问题,设 f(n) 表示错排方案数,g(n) 表示随便放,则 g 可以写成关于 f 的形式:

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

即为枚举哪些人站错了,剩下的人都站对了。

考虑一个显然正确的式子:

f(n)=m=0n[m=n](nm)f(m)

对于艾佛森括号,我们可以通过二项式定理展开,即:

(11)n=i=0n(ni)(1)i=[n=0]

再次代入:

f(n)=m=0ni=0nm(nmi)(1)i(nm)f(m)

其中有两个组合数,考虑组合意义:先在 n 种选 m 个,再从剩下的选 i 个,先后顺序是不重要的,所以有:

f(n)=m=0ni=0nm(1)i(ni)(nim)f(m)

交换求和符号:

f(n)=i=0n(1)i(ni)m=0ni(nim)f(m)

不难发现后面的式子即为 g(ni)

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

t=ni,则 i=nt

f(n)=t=0n(1)nt(nt)g(t)

证毕。

“至多/至少"和"恰好"的转换

g(n)=i=0n(ni)f(i)f(n)=i=0n(1)ni(ni)g(i)g(k)=i=kn(ik)f(i)f(k)=i=kn(1)ik(ik)g(i)

考虑组合意义,上式的 g(i) 表示 至多i,下式表示 至少 i。右侧 f 均表示恰好 i

应用在于算容斥系数。

例题1:P4859 已经没有什么好害怕的了

给定两个序列,ai,bi,要求两两配对使得 aj>bk 的配对数减去 aj<bk 的配对数恰好等于 t,求方案数。tn2000。保证 a,b 互不相同。

因为没有相等的元素,所以 a>b 的个数一定是 n+k2。特判掉 n+k 为奇数的情况。

问题变成了计数 a>b 恰好为 k 的方案。

我们肯定需要分别升序排序,然后考虑 ai 匹配了哪个位置上的 bj

fi,j 表示考虑 a 的前 i 个位置已经匹配,此时比 ai 小的 b 还有 j 个:

如果当前 ai 匹配了一个小于 aib,那么下一个 ai+1 会减少一个能够匹配的 j

但是如果匹配了一个大于 aib,下一个 ai+1 不好确定是否会减少,这样看似只能状压,如何刻画?

考虑反演。我们要计算 恰好有 k 对匹配,通过二项式反演,我们也可以求 至少有 k 对匹配

fi,j 表示至少匹配了 j<a 的匹配,那么每次要么不匹配,匹配的方案有 sj 种,其中 s 是小于 aib 的个数。

f[i][j]=f[i1][j]+f[i1][j1](sj)

gi 表示至少 i 对匹配,有 gi=(ni)!fn,i,前面的阶乘表示剩下的随便乱选。

然后对于恰好的转换就是:ans=i=kn(1)ik(ik)g(i)

降智错误:最后的 k,实际上是 (n+k)/2!!!

子集反演

定理内容

g[S]=T\subSf[T]

则有:

f[S]=T\subS(1)|S||T|g[T]

证明

类似的,我们可以反演艾佛森括号:

T\subS(1)|T|=[|S|=0]

等价于二项式反演,因为元素大小为 |T| 的元素有 (|S||T|) 个。

f[S]=T\subS[|S|=|T|]f[T]f[S]=T\subSP\subST(1)|P|f[T]f[S]=P\subS(1)|P|T\subSPf[T]f[S]=P\subS(1)|P|g[SP]f[S]=P\subS(1)|S||P|g[P]

P6442 [COCI2011-2012#6] KOŠARE

给定 n 个箱子,每个箱子中有若干件物品,所有物品的种类数 m20,求选择箱子的方案数,使得每种物品都被包含。n106

直接做不好做,显然用子集反演,但是是选择“至少”还是“至多”呢?

我们考虑 f[S] 表示选的物品是 S 的子集的方案数,ans=T\sub2m(1)m|T|f[T]

再求出 g[S] 表示有多少箱子是 S 的子集,f[S]=(2g[S]1)

可以发现 g[S] 相当于高维前缀和。

[ARC101E] Ribbons on Tree

给定大小为 n 的树,给树上的点两两配对,对于每一组配对 (u,v) 将其路径上的边全部覆盖,定义一个配对方案合法,当且仅当每一条边都被覆盖。n5000 且是偶数。

套路的,有 O(n3) 的 DP:

fu,i 表示 u 为根的子树内有 i 个点未匹配的方案数,转移用 fu,i×fv,j×(ik)(jk)fu,i+jk

这样没有优化的空间了,考虑子集反演(容斥):

ans=S\subE(1)

P3813 [FJOI2017] 矩阵填数

给定一个 h×w 的矩阵,每个位置可以填 [1,m] 的数。

n 个限制:表示一个子矩阵的最大值为 v

求方案数。h,w,m104,n10

对于多个矩形,满足条件是不好做的,但是不满足条件是好做的,只需要 svsv1 即可,其中 s 是这个矩形的点个数。

f(S) 表示至少打破 S 集合内的限制,最终求恰好打破 0 个限制,直接子集反演。

因为 n 只有 10,我们可以先离散化,这样有用的点就是 O(n) 个了。

这样暴力遍历矩形并 checkmin,可以在 O(n3) 求出 f(S)

时间复杂度 O(2nn3)

当走不动的时候多想想离散化,NOIP2023T4说不定就拿满了。

这里二维矩形的离散化来整理一下,两种思路:

  1. 每个点保存以其为右上角的矩形,放在一维上存的是 (xi1,xi] 左开右闭,注意到这样可以充分利用 x[0]=0,但仍要加入 x[n+1]=h

    对于输入矩形 (x1,y1,x2,y2),因为左开右闭,所以实际上存的是 (x11,y11,x2,y2),进行遍历的时候,实际上是:

    for(int x=q[j].x1+1;x<=q[j].x2;x++) {
        for(int y=q[j].y1+1;y<=q[j].y2;y++) {
            a[x][y]=min(a[x][y],q[j].v-1);
        }
    }
    for(int x=1;x<=tot1;x++) {
        for(int y=1;y<=tot2;y++) {
            int s=(X[x]-X[x-1])*(Y[y]-Y[y-1]);	
            ans=ans*ksm(a[x][y]%mod,s)%mod;	
        }
    }
    
  2. 每个点保存以其为左下角的矩形,放在一维上是左闭右开,这样需要加入 x[1]=1,x[n+1]=h+1

    对于输入矩形,其右上角要加一,遍历的时候只能到右端点减一。

都可以先从一维上考虑,理清思路再写,检查考场上会写慌。

[SHOI2016] 黑暗前的幻想乡

有一张无向完全图,每条边有一个颜色,总共有 n1 种颜色,求恰好有 n1 种颜色的生成树个数。n17

这题也非常牛!

如果已知一个无向图,那么我们很好用矩阵数定理求生成树个数。

但是颜色的限定很制,限制表示一个颜色只能选一条边,我们枚举选的颜色集合,表示至多打破这些颜色的限制,形成的生成树个数,最终要求的是恰好打破 0 个颜色限制的个数。子集反演即可。

Min-max 容斥

定理内容

(1)max(S)=T\subS(1)|T|+1min(T)

证明

对于每一个 aiT,考虑其作为最小值的贡献次数,显然,小于 ai 的不能选,不妨设大于 ai 的有 k 个,枚举,则有:

i=0k(ki)(1)i+1+1

由二项式反演易知其结果为 [k=0],即只有最大值能有贡献。

期望形式

(2)E(maxS)=T\subS(1)|T|1E(minT))

扩展形式

(3)kthmax(S)=T\subS,|T|k(1)|T|k(|T|1k1)minT

P3175 [HAOI2015] 按位或

初始手上有一个 0,每一秒你可以选择一个 [0,2n1] 的数字与手上的数字进行按位或,选择 i 的概率是 pi,问期望多少秒后手上的数字变成 2n1n20

前置知识:离散随机变量的几何分布

这是高中数学吗?

抛出一个六面的筛子,丢出数字 1 的期望是多少?答案即为 1/(1/6)=6

证明:

E(x)=i=1infiP(x=i)E(x)=i=1infP(xi)E(x)=i=1inf(1p)i1E(x)=i=0inf(1p)i=1(1p)inf1(1p)=1p

我们把 n 为二进制直接看成集合,定义集合的 max集合中最后一个位置变成 1 的时间,定义 min集合中第一个位置变成 1 的时间。这样做的原因是第一个位置变成 1 是好求的。

E(minS)=1pp=1T\sub(US)PT

注意我们求概率 p 的时候就已经不关心试了几次了,只用求一次的情况。

因此,我们只需计算一遍高维前缀和即可,如果最后要求任意结束位置,则需要求两遍高维前缀和。

P4707 重返现世

[PKUWC2018]随机游走

有根树,初始给定起点。每次询问树上随机游走经过一个点集中所有点至少一次的期望步数。 n18

相当于求集合最后一个点经过的时间,可以用Min-Max容斥转换为求第一个点经过的时间。

根据期望的套路,可以直接dp,设 fi,s 表示从 i 出发,第一次走过 s 内任意一个点的期望时间,有转移:

f_{i,s}=1+\frac{1}{deg_i}(f_{fa,s}+\sum f_{v,s}) & (i\notin s) \\ f_{i,s}=0 &(i\in S)

需要高斯消元,时间复杂度 O(n33n)

对于树上需要高斯消元的问题,如果我们将转移方程写成关于父亲的函数,那么可以在 O(n) 时间做树上高消

具体的,设 fi=Aiffa[i]+Bi,则转移方程可以写成:

degifi=ffa[i]+((vson[i])av)fi+(vson[i]bv)+degiAi=1degiav,Bi=bv+degidegiav

非常牛,A,B 均只与子树信息有关,同时和 S 无关可以直接一遍树形 dp 得到

错误的,不要忘了 S 的限制,当 xS 的时候直接 return 即可。

P3600 随机数生成器

斯特林反演

posted @   Apricity8211  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示