【2】容斥与二项式反演

【2】容斥与二项式反演#

1.1 容斥原理#

容斥原理基于的是下面的恒等式:

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

这个式子有什么意义呢?我们考虑一个长度为 N 的序列,并且要求其中每个元素都满足某个限制,计算满足这个条件的序列数量。

每个元素都满足限制 不满足限制的元素个数为 0

那么容斥原理告诉我们的是,满足上述限制的序列个数等于:我们钦定若干元素 不满足限制,剩下的元素任意,如果钦定的元素个数是 t,那么就用这样的方案数乘上 (1)t 求和。

我们考虑为什么是对的?

我们记 n 为不满足条件的元素个数, 那么当 n>0 时,我们会对其每个子集做一遍钦定,那么总的被算的次数就是 i=0n(ni)(1)i=0,也就是说对答案的贡献被抵消了!

同样的,当 n=0 时,恰好会被算一次,那么我们就只计算了 n=0 也就是所有元素都满足限制的序列个数。

这样做有什么好处呢?我们做容斥之后,元素分成了两类,被钦定不满足限制的和任意的,通常不满足限制的元素一定满足一些性质,而任意的自然不用管,于是就可以转化问题。

在很多时候,我们并不需要真的枚举子集,可以考虑一个 dpi,j 表示考虑了前 i 个元素,已经钦定了 j 个的方案数,最后乘上 (1)j 求和。

但这真的最优吗?我们考虑去掉 j 这一维,每次如果加入一个被钦定元素就给 dp 值乘上 1,这样恰好被乘了 j 次,因此我们这个容斥并不会增加复杂度!

例一P1595 信封问题#

计算有多少个排列 pi 满足 pii

我们套用上面的分析模式,钦定若干元素不满足限制,也就是 pi=i,剩下的任意,也就是全排。

那么我们假设钦定了 j 个元素,那么一共有 (nj) 个子集,剩下的就是 (nj)!,不要忘了乘上 (1)j

答案就是 j=0n(1)j(nj)(nj)!

例二[JSOI2011] 分特产#

还是一样,钦定若干人分不到特产,剩下的随意,假设还剩下 ni 个人,那么对于一个有 aj 个的物品,方案数就是插板法 (aj+ni1ni1)

复杂度 Θ(nm)

例三 P3301 [SDOI2013] 方程#

假如只有 xiai 的限制,我们是可以 Θ(1) 算的,令 yi=xiai,那么就变成:

yi0,yi=mai,可以直接插板。

现在还有 xiai 的限制怎么办?钦定若干 xi 不满足,也就是 ai+1,那么就变成了前者。

复杂度 Θ(n12n1),但是傻逼出题人强迫你写 exlucas。

例三(2)HAOI2008 硬币购物#

和上面基本一样,只是换成了完全背包。

例四:#

计算有多少个序列 a,满足 ai[1,m]aiai+1

直接用组合的角度考虑,第一个数有 m 种,后面每个都有 m1 种,一共有 m(m1)n1 种。

那从容斥的角度呢?

我们这次不对点容斥,而是钦定若干个 (i,i+1),也就是钦定若干 ai=ai+1

考虑 dp,fi 表示考虑了前 i 个时的 dp 数组,我们考虑 (i1,i) 是否钦定:

  • 如果不钦定,那么 i 就可以任意选 fi=fi+mfi1
  • 如果钦定,那么 i 就只有一种选法,带上容斥系数就是 fi=fi+(1)fi1

这个 dp 有点蠢啊,我们可以发现钦定的点形成了若干个区间,每个区间内是相等的,并且假如我们钦定了 i 条边,那么就形成了 ni 个区间,一共有 (1)imni 的贡献。

那么答案就是 i=0n1(n1i)(1)imni=m(m1)n1,得到了同样的结果。

我们接下来会说明这个 dp 和这个组合数都比一开始的做法更具拓展性。

例四的拓展#

计算有多少个序列 a,满足 ai[1,m]aiai+1,且 airi

此时每个数有了上界的限制,我们不能直接 Θ(1) 算了。

还是考虑上边那个容斥的思路,同样的还是每个被钦定的边构成了若干个区间,每个区间内是相等的,那么这些数一共有 mini=LRri 种选法。

还是考虑那个 dp,此时我们暴力枚举当前点 i 所属区间的左端点 j,然后 dpi=dpi+(1)ijdpj1min{rj,,ri},暴力做就可以做到 Θ(n2)

能不能再给力点啊?

做法一:

我们考虑随着 i 的增加,min{rj,,ri} 是怎么变化的,我们考虑一下维护一个单调栈,那么每次一定是 ri 弹掉了若干比 ri 大的数,也就是对 min{rj,,ri} 的影响是一个区间赋值!

那么我们可以开一棵线段树,维护 (1)ijdpj1min{rj,,ri} ,那么就是一个区间赋值,单点修改,区间求和,然后就做到了 Θ(nlogn)

做法二:

更暴力的,直接记录 dpi,v 表示当前到了第 i 个,当前区间的 min=v ,转移时:

  • 如果不钦定那么 dpi,ri+=v×dpi1,v
  • 如果钦定并且 ri<v,那么 dpi,ri+=(1)dpi1,v
  • 如果钦定并且 riv,那么 dpi,v=dpi1,v(1)

可以发现需要支持区间乘法,单点修改,区间求和,建一棵值域线段树即可。

如果要拓展到树上怎么做?把做法二的值域线段树改成线段树合并即可。

例五[ARC101E] Ribbons on Tree#

我们转换一下容斥的对象,我们这次对树上的边容斥。

题目的限制是每条边至少被经过一次,那么我们就钦定一个边集,这里面的边都不被经过,此时有什么性质呢?

我们可以发现,每条不被经过的边把树划分成了若干个连通块,每个连通块是独立的!并且因为连通块内的边经不经过都无所谓,所以如果一个连通块大小为 S,那么这个连通块的配对的方案数就是 (S1)(S3)(S5),和树的形态是无关的。

那么我们考虑树形 DP,dpx,i 表示在 x 子树内,当前点所在连通块的大小为 i 的方案数的和,转移的时候,枚举 x 的儿子 y 以及 y 所在块的大小 j,并考虑这条边被不被钦定:

  • 如果不钦定,那么让 x,y 所在连通块合并,大小相加。
  • 如果钦定,那么就用 y 的方案数乘上 (j1)(j3),对了还要乘上 1

因为 isizx,所以复杂度就是树背包的复杂度 Θ(n2)

例六2487. 水仙花#

计算有多少个长度为 n,值域为 [1,m] 的序列 a,对于 i[1,n1],下面两个条件至少满足一个:

  • aiai+1
  • aimodai+1>0

钦定若干 i 都不满足,也就是 ai>ai+1,aimodai+1=0,也就是 ai+1ai 的真因子。

和上面的类似,最终被钦定的构成若干段区间,那么因为真因子每次至少 /2,所以每段区间的长度不超过 log2n

预处理 fi,j 表示长度为 i,且第一个数是 j 的序列个数,转移枚举 j 的倍数,复杂度 Θ(mlog2m)

然后设 dpi 表示考虑前 i 个的方案数,每次枚举一段区间转移即可,复杂度 Θ(nlogm)

例七 [ZJOI2022] 树#

非叶子是不好确定的,我们考虑把非叶子容斥成叶子。

对于每个点,有如下情况:

  • 第一棵树非叶子,第二棵树叶子:

    • 选择容斥,变成第一棵树叶子,第二棵树叶子。
    • 不选择容斥,变成第一棵树任意,第二棵树叶子。
  • 第一棵树叶子,第二棵树非叶子:

    • 选择容斥,变成第一棵树叶子,第二棵树叶子。
    • 不选择容斥,变成第一棵树叶子,第二棵树任意。

    dpi,j,k 表示考虑前 i 个点,[1,i] 在第一棵树上有 j 个叶子,[i+1,n] 在第二棵树上有 k 个叶子,转移是:

    • dpi+1,j+1,k1+=(1)dpi,j,k(ij)(ni1k)
    • dpi+1,j,k1+=dpi,j,k(ij)(ni1k)
    • dpi+1,j+1,k1+=(1)dpi,j,k(ij)(ni1k)
    • dpi+1,j+1,k+=dpi,j,k(ij)(ni1k)

    复杂度 Θ(n3)

例八 [NOI2020] 命运#

对路径容斥,钦定若干路径上的边都是 0,剩下的路径不限制。

考虑一个 dpdpi,j 表示在 i 的子树内,当前还存在的路径中,上端点最浅的深度为 j 的方案数。

合并子树 dpy,k 时,如果 k=depy,这条边就 0/1 都可以选,否则就必选填 0,同时令 j=min(j,k)

加入路径时,如果不容斥就不更新,如果容斥就令 j=min(j,k)

用线段树合并维护 dp 数组,需要打乘法标记,维护区间和。

复杂度 Θ(nlogn)

1.2 二项式反演#

所谓的二项式反演,其实是容斥的一种拓展情况,我们之前求的是所有元素都满足某个限制的个数,而二项式反演通常解决的是:恰好k 个元素满足某个限制的序列个数。

我们设这个问题的答案是 fk,仿照前面的思路,我们钦定 k 个元素满足限制,剩下任意,记为 gk

那么 f,g 有什么关系呢,考虑对于 fk,gj,kj,那么 fkgj 算了 (kj) 次,也就是说:

gj=k=jn(kj)fk

假如我们可以算 g,那么怎么从 g 得到 f 呢,事实上:

fj=k=jn(1)kj(kj)gk

我们不妨展开右边式子:

k=jn(1)kj(kj)i=kn(ik)fi

=i=jnfik=ji(1)kj(ik)(kj)

=i=jnfik=ji(1)kj(ij)(ijkj)

=i=jn(ij)fik=0ij(1)k(ijk)

=i=jn(ij)fi[ij=0]

=fj

因此得证。

当然,因为恰好 k 个满足等于 恰好 nk 个满足,所以通常情况是对 nk 进行容斥的,和上面是一样的。

P10596 BZOJ2839 集合计数#

fk 表示钦定 k 个元素在他们的交集内,其他任意的方案数。

那么包含这 k 个集合的子集个数有 2nk,选出至少一个的方案数是 22nk1,乘上选出 k 个元素的方案数 (nk),然后二项式反演回原式即可。

已经没有什么好害怕的了#

因为总共有 n 组,所以可以得出 “糖果比药片能量大” 的恰好有 n+k2 组。

把糖果和药片都从小到大排序,设 fi,k 表示考虑了前 i 小的糖果,其中钦定了 k 组的方案数,转移时,如果不钦定,我们可以最后乘上一个 (nk)! 即可;如果钦定,那么求出可以和第 i+1 个糖果在一组的药片数量 j,其中已经有 k 个被用过了,所以方案数就是 jk

最后二项式反演回原问题,复杂度 Θ(n2)

[NOI Online #2 提高组] 游戏#

求出 gk 表示恰好选出 k 对祖先-子孙点且颜色不同的方案数,最后乘上 m! 即可。

套路的,钦定若干对祖先-子孙点,设 fi,k 表示 i 的子树内,钦定了 k 对节点的方案数。

合并子树就是背包,而对于节点 i,不选择钦定的话最后乘上 (mk)! 即可,选择钦定的话,如果子树内有 si 个和 i 颜色不同的节点,那么可以和 i 匹配的就有 sik 个,乘上即可。

最后二项式反演出 g,复杂度 Θ(n2)

CF285E Positions in Permutations#

还是求出钦定若干位置满足 |ipi| 的方案数,二项式反演回去。

fi,k 表示前 i 个位置,钦定了 k 个的方案数,对于不被钦定的位置我们还是最后乘上 (nk)!

那么其实我们只关注 i,i+1 是否被选即可,复杂度 Θ(n2)

可以发现大部分二项式反演的题都是一个套路

1.3 另一些容斥问题#

  • 有平面上的 k 个障碍,要求从 (0,0) 开始,每次向上或者向右走到 (n,m) 不能经过障碍点的方案数,0k1000,n,m105

直接求很难求,我们钦定若干障碍点必须经过,其他的无所谓。

dpi 表示钦定第 i 个障碍点必须经过时,从 (0,0) 走到第 i 个障碍点的方案数。

转移时枚举上一个被钦定的障碍点 j,那么方案数就是 dpj(xixj+yiyjxixj)

复杂度 Θ(n2)

[THUPC2019] 过河卒二#

首先,可以从上边和右边走出棋盘,等价于我们走到 (n+1,m+1)

然后对于障碍点做上述的容斥 dp,只不过不同的是这次可以斜着走。

假设我们要从 (0,0) 走到 (X,Y),枚举向右上走的次数 i,那么方案数可以表示为:

i=0min(X,Y)(X+Yii)(X+Y2iXi)

组合数用 lucas 算,复杂度 Θ(mk2)

[HAOI2017] 方案数#

现在有三维了!有什么区别吗

容斥的部分和上面是一样的,我们的问题还是预处理从 (0,0,0) 走到 (X,Y,Z) 的方案数。

这个状态有点大啊,不过仔细分析一下会发现实际上只和 X,Y,Z1 的个数有关。

dpi,j,k 表示走到 |X|=i,|Y|=j,|Z|=k 的方案数,转移的时候,枚举下一次操作,假设是操作 X,那么转移应该是 dpi,j,k=dpi,j,k+dpi,j,k(ii)
于是就做完了,复杂度 Θ(o2)

  • 求出 n 个点的无向连通图数量。

fi 表示 i 个点的无向连通图数量,那么可以用 “总的图的数量” 减掉 “不连通的图的数量”。

前者就是 2n(n1)/2,对于后者,我们枚举一号点所在连通块的大小 j(j<i),那么剩下的部分和这 j 个点不连通,转移为:

fi=2n(n1)/2j=1i1(i1j1)fj2(ij)(ij1)/2

分别代表选出 j1 个点组成连通块的方案数,连通块内部的方案数,以及外部的方案数。

复杂度 Θ(n2)

[清华集训2012] 串珠子#

因为 n 很小,所以我们考虑状压。

gS 表示集合 S 内部的点构成的图的总数,fS 表示集合 S 内的点构成连通图的方案数,转移时还是枚举 1 所在连通块的点集。

fS=gSTS,1TfTgST

复杂度 Θ(2nn2+3n)

posted @   Larunatrecy  阅读(122)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
点击右上角即可分享
微信分享提示
主题色彩