【2】容斥与二项式反演
【2】容斥与二项式反演#
1.1 容斥原理#
容斥原理基于的是下面的恒等式:
这个式子有什么意义呢?我们考虑一个长度为 的序列,并且要求其中每个元素都满足某个限制,计算满足这个条件的序列数量。
每个元素都满足限制 不满足限制的元素个数为 。
那么容斥原理告诉我们的是,满足上述限制的序列个数等于:我们钦定若干元素 不满足限制,剩下的元素任意,如果钦定的元素个数是 ,那么就用这样的方案数乘上 求和。
我们考虑为什么是对的?
我们记 为不满足条件的元素个数, 那么当 时,我们会对其每个子集做一遍钦定,那么总的被算的次数就是 ,也就是说对答案的贡献被抵消了!
同样的,当 时,恰好会被算一次,那么我们就只计算了 也就是所有元素都满足限制的序列个数。
这样做有什么好处呢?我们做容斥之后,元素分成了两类,被钦定不满足限制的和任意的,通常不满足限制的元素一定满足一些性质,而任意的自然不用管,于是就可以转化问题。
在很多时候,我们并不需要真的枚举子集,可以考虑一个 表示考虑了前 个元素,已经钦定了 个的方案数,最后乘上 求和。
但这真的最优吗?我们考虑去掉 这一维,每次如果加入一个被钦定元素就给 值乘上 ,这样恰好被乘了 次,因此我们这个容斥并不会增加复杂度!
例一P1595 信封问题#
计算有多少个排列 满足 。
我们套用上面的分析模式,钦定若干元素不满足限制,也就是 ,剩下的任意,也就是全排。
那么我们假设钦定了 个元素,那么一共有 个子集,剩下的就是 ,不要忘了乘上 。
答案就是 。
例二[JSOI2011] 分特产#
还是一样,钦定若干人分不到特产,剩下的随意,假设还剩下 个人,那么对于一个有 个的物品,方案数就是插板法 。
复杂度 。
例三 P3301 [SDOI2013] 方程#
假如只有 的限制,我们是可以 算的,令 ,那么就变成:
,可以直接插板。
现在还有 的限制怎么办?钦定若干 不满足,也就是 ,那么就变成了前者。
复杂度 ,但是傻逼出题人强迫你写 exlucas。
例三(2)HAOI2008 硬币购物#
和上面基本一样,只是换成了完全背包。
例四:#
计算有多少个序列 ,满足 。
直接用组合的角度考虑,第一个数有 种,后面每个都有 种,一共有 种。
那从容斥的角度呢?
我们这次不对点容斥,而是钦定若干个 ,也就是钦定若干 。
考虑 dp, 表示考虑了前 个时的 dp 数组,我们考虑 是否钦定:
- 如果不钦定,那么 就可以任意选 。
- 如果钦定,那么 就只有一种选法,带上容斥系数就是 。
这个 dp 有点蠢啊,我们可以发现钦定的点形成了若干个区间,每个区间内是相等的,并且假如我们钦定了 条边,那么就形成了 个区间,一共有 的贡献。
那么答案就是 ,得到了同样的结果。
我们接下来会说明这个 dp 和这个组合数都比一开始的做法更具拓展性。
例四的拓展#
计算有多少个序列 ,满足 ,且 。
此时每个数有了上界的限制,我们不能直接 算了。
还是考虑上边那个容斥的思路,同样的还是每个被钦定的边构成了若干个区间,每个区间内是相等的,那么这些数一共有 种选法。
还是考虑那个 dp,此时我们暴力枚举当前点 所属区间的左端点 ,然后 ,暴力做就可以做到 。
能不能再给力点啊?
做法一:
我们考虑随着 的增加, 是怎么变化的,我们考虑一下维护一个单调栈,那么每次一定是 弹掉了若干比 大的数,也就是对 的影响是一个区间赋值!
那么我们可以开一棵线段树,维护 ,那么就是一个区间赋值,单点修改,区间求和,然后就做到了 。
做法二:
更暴力的,直接记录 表示当前到了第 个,当前区间的 ,转移时:
- 如果不钦定那么 。
- 如果钦定并且 ,那么 。
- 如果钦定并且 ,那么 。
可以发现需要支持区间乘法,单点修改,区间求和,建一棵值域线段树即可。
如果要拓展到树上怎么做?把做法二的值域线段树改成线段树合并即可。
例五[ARC101E] Ribbons on Tree#
我们转换一下容斥的对象,我们这次对树上的边容斥。
题目的限制是每条边至少被经过一次,那么我们就钦定一个边集,这里面的边都不被经过,此时有什么性质呢?
我们可以发现,每条不被经过的边把树划分成了若干个连通块,每个连通块是独立的!并且因为连通块内的边经不经过都无所谓,所以如果一个连通块大小为 ,那么这个连通块的配对的方案数就是 ,和树的形态是无关的。
那么我们考虑树形 DP, 表示在 子树内,当前点所在连通块的大小为 的方案数的和,转移的时候,枚举 的儿子 以及 所在块的大小 ,并考虑这条边被不被钦定:
- 如果不钦定,那么让 所在连通块合并,大小相加。
- 如果钦定,那么就用 的方案数乘上 ,对了还要乘上 。
因为 ,所以复杂度就是树背包的复杂度 。
例六2487. 水仙花#
计算有多少个长度为 ,值域为 的序列 ,对于 ,下面两个条件至少满足一个:
- 。
钦定若干 都不满足,也就是 ,也就是 是 的真因子。
和上面的类似,最终被钦定的构成若干段区间,那么因为真因子每次至少 /2,所以每段区间的长度不超过 。
预处理 表示长度为 ,且第一个数是 的序列个数,转移枚举 的倍数,复杂度 。
然后设 表示考虑前 个的方案数,每次枚举一段区间转移即可,复杂度 。
例七 [ZJOI2022] 树#
非叶子是不好确定的,我们考虑把非叶子容斥成叶子。
对于每个点,有如下情况:
第一棵树非叶子,第二棵树叶子:
- 选择容斥,变成第一棵树叶子,第二棵树叶子。
- 不选择容斥,变成第一棵树任意,第二棵树叶子。
第一棵树叶子,第二棵树非叶子:
- 选择容斥,变成第一棵树叶子,第二棵树叶子。
- 不选择容斥,变成第一棵树叶子,第二棵树任意。
设 表示考虑前 个点, 在第一棵树上有 个叶子, 在第二棵树上有 个叶子,转移是:
- 。
- 。
- 。
- 。
复杂度 。
例八 [NOI2020] 命运#
对路径容斥,钦定若干路径上的边都是 ,剩下的路径不限制。
考虑一个 , 表示在 的子树内,当前还存在的路径中,上端点最浅的深度为 的方案数。
合并子树 时,如果 ,这条边就 都可以选,否则就必选填 ,同时令 。
加入路径时,如果不容斥就不更新,如果容斥就令 。
用线段树合并维护 dp 数组,需要打乘法标记,维护区间和。
复杂度 。
1.2 二项式反演#
所谓的二项式反演,其实是容斥的一种拓展情况,我们之前求的是所有元素都满足某个限制的个数,而二项式反演通常解决的是:恰好有 个元素满足某个限制的序列个数。
我们设这个问题的答案是 ,仿照前面的思路,我们钦定 个元素满足限制,剩下任意,记为 。
那么 有什么关系呢,考虑对于 ,那么 被 算了 次,也就是说:
假如我们可以算 ,那么怎么从 得到 呢,事实上:
我们不妨展开右边式子:
因此得证。
当然,因为恰好 个满足等于 恰好 个满足,所以通常情况是对 进行容斥的,和上面是一样的。
P10596 BZOJ2839 集合计数#
设 表示钦定 个元素在他们的交集内,其他任意的方案数。
那么包含这 个集合的子集个数有 ,选出至少一个的方案数是 ,乘上选出 个元素的方案数 ,然后二项式反演回原式即可。
已经没有什么好害怕的了#
因为总共有 组,所以可以得出 “糖果比药片能量大” 的恰好有 组。
把糖果和药片都从小到大排序,设 表示考虑了前 小的糖果,其中钦定了 组的方案数,转移时,如果不钦定,我们可以最后乘上一个 即可;如果钦定,那么求出可以和第 个糖果在一组的药片数量 ,其中已经有 个被用过了,所以方案数就是 。
最后二项式反演回原问题,复杂度 。
[NOI Online #2 提高组] 游戏#
求出 表示恰好选出 对祖先-子孙点且颜色不同的方案数,最后乘上 即可。
套路的,钦定若干对祖先-子孙点,设 表示 的子树内,钦定了 对节点的方案数。
合并子树就是背包,而对于节点 ,不选择钦定的话最后乘上 即可,选择钦定的话,如果子树内有 个和 颜色不同的节点,那么可以和 匹配的就有 个,乘上即可。
最后二项式反演出 ,复杂度 。
CF285E Positions in Permutations#
还是求出钦定若干位置满足 的方案数,二项式反演回去。
设 表示前 个位置,钦定了 个的方案数,对于不被钦定的位置我们还是最后乘上 。
那么其实我们只关注 是否被选即可,复杂度 。
可以发现大部分二项式反演的题都是一个套路
1.3 另一些容斥问题#
- 有平面上的 个障碍,要求从 开始,每次向上或者向右走到 不能经过障碍点的方案数,。
直接求很难求,我们钦定若干障碍点必须经过,其他的无所谓。
设 表示钦定第 个障碍点必须经过时,从 走到第 个障碍点的方案数。
转移时枚举上一个被钦定的障碍点 ,那么方案数就是 。
复杂度 。
[THUPC2019] 过河卒二#
首先,可以从上边和右边走出棋盘,等价于我们走到 。
然后对于障碍点做上述的容斥 ,只不过不同的是这次可以斜着走。
假设我们要从 走到 ,枚举向右上走的次数 ,那么方案数可以表示为:
组合数用 lucas 算,复杂度 。
[HAOI2017] 方案数#
现在有三维了!
有什么区别吗容斥的部分和上面是一样的,我们的问题还是预处理从 走到 的方案数。
这个状态有点大啊,不过仔细分析一下会发现实际上只和 的 的个数有关。
设 表示走到 的方案数,转移的时候,枚举下一次操作,假设是操作 ,那么转移应该是 。
于是就做完了,复杂度 。
- 求出 个点的无向连通图数量。
设 表示 个点的无向连通图数量,那么可以用 “总的图的数量” 减掉 “不连通的图的数量”。
前者就是 ,对于后者,我们枚举一号点所在连通块的大小 ,那么剩下的部分和这 个点不连通,转移为:
分别代表选出 个点组成连通块的方案数,连通块内部的方案数,以及外部的方案数。
复杂度 。
[清华集训2012] 串珠子#
因为 很小,所以我们考虑状压。
设 表示集合 内部的点构成的图的总数, 表示集合 内的点构成连通图的方案数,转移时还是枚举 所在连通块的点集。
。
复杂度 。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?