前言
可能需要一点二项式定理和二项式反演的相关知识。
有许多不足还请指出。
公式
经典容斥
均为有限集,,则
可以用数学归纳法严格证明,我有个简单点的。
考虑 中任一元素 ,若共有 个集合包含 ,其对答案的贡献为
即每个元素都仅对答案产生 的贡献。
组合容斥
组合容斥中,容斥系数变为了组合数。
有个简单的引例,若 ,则有
证明如下:
考察式子右半边,令 ,则
即 。
现在改变 的含义, 表示所有 的 之和,发现每个大小为 的集合任选 个都会对 产生 的贡献,即 ,由二项式反演得
有的题容斥系数可能更为复杂,对于如何求容斥系数,可以对每种情况考虑其应被计算次数,并列出方程来求解。
容斥
给定集合 , 表示 中最大值, 表示 中最小值,则有
对第一个式子证明。将 中的元素从大到小排序,考虑第 大的应元素被计算几次。
对于第 大的元素,当它以 呈现时,说明 中的元素均是第 至第 大的,且必须包含第 大的元素。
故第 个数会被计算 次。
特别地,当 时,会被计算一次,即只有 被计算了一次。
的证明同理。
容斥还可以推广到第 大, 表示集合 中第 大的元素,设 为容斥系数,则 。
对于第 大的元素,我们希望它被计算 次,可列出方程
由二项式反演得
即
主要用来解决集合概率问题。
例题
BZOJ3589 动态树
给你一棵 个点的树, 次操作,支持
- 子树内每个点权加
- 查询 条链的并集点权和
保证给出的链深度递增。
直接求并不好求,可以用容斥把问题转化为枚举 种情况求交,这题的链深度递增,求交是相当简单的。
直接树剖维护是 的,去到了 。
因为这题的链深度递增,所以链求和可以直接维护到根的路径上点权和,作差就可以了,这样一次修改是 ,一次查询是 ,总复杂度是 ,去掉了一个 。
然后对于 子树内的一点 ,一次加 会使 处增加 ,前后两部分分开维护即可。
CQOI2012 局部极小值
对于一个 的矩阵, 被认为是好的当且仅当 比其周围 个数均更小。给出矩阵中好的元素位置,求可能的矩阵方案数。
所有的 构成一个 的排列。
为保证构造矩阵合法,可以从小到大填数,目标位置周围显然不能填。
发现最多可存在的好的元素数量很少,可以把这些位置压缩成一个状态进行 dp,关键点位置的转移直接从前驱转移即可,未填数的关键点周围不可转移,其他位置随便放即可,转移方程很好写。
注意到这样 dp 出来的方案数可能会包含更多的关键点,所以要容斥一下,具体而言,若题目给出 个关键点,最多存在 个关键点,则答案为 。
因为 很小,所以直接搜索,在原有集合上扩展,每次把多一个的答案减掉即可。
复杂度不太会算,跑得挺快。
P4859 已经没什么好害怕的了
给出序列 ,一个排列 的权值为 ,求权值为 的排列个数。
简化题意的 是原题的 。
考虑 dp,先将 排序,发现当 选择一个比它小的 时,对后面的选择不会有本质影响,而选择比它大的 会很复杂。
这启发我们在 dp 中设计匹配个数的状态,最后统一分配剩下的 , 表示考虑到第 项,有 个 满足 的情况数,记 表示 序列中比 小的元素个数个数,有转移方程 。
之后考虑剩下 对答案的影响,令 ,表示剩下的数任意放的情况数,发现可能会产生更多的匹配,且同一种排列可能会被计算多次,考虑组合容斥。
令 表示权值恰好等于 的排列数,有
可以理解为 中的每种排列从 个匹配中任取 个出来都会对 有 的贡献。
由二项式反演得
SCOI2010 幸运数字
一个数字是幸运数字当且仅当它每一位均由 或 组成。
一个数字是类幸运数字当且仅当它是幸运数字的倍数。
求区间 内类幸运数字的个数。
发现最多只有 个幸运数字,记为序列 ,可以预处理出来,令 表示幸运数字个数。
问题转化为 中有多少个数是 中任意一个数的倍数。
这就是个经典的容斥问题了,其实就是若干个集合求并。
令 表示 中 的倍数个数,则
直接做是 的,考虑一些剪枝。
首先可以把这里面有倍数关系的都去掉,这样只剩 个数了。
因为 大于 时肯定不会有贡献了,可以直接返回,这让复杂度大大降低。
然后可以将 从大到小排序,让 更快超过 。
这三个剪枝加完就能通过本题了。
BZOJ2839 集合计数
一个 个元素的集合,从它的子集(包括空集)中取出若干个集合,使它们的交集大小为 ,求可能的取法总数。
用 表示交集大小至少为 的答案,首先钦定 个交集的元素,共有 种情况,剩下的 个数组成的集合,共有 个子集,每个子集可以选或不选,但不能都不选,要去掉空集,所以共有 种取法,即 。
这样也会有一个集合内相同元素算了多次的问题,考虑组合容斥,令 表示交集大小恰为 的答案,有
可理解为在交集 个元素中钦定 个作为 中的交集,每次有 贡献。
由二项式反演得
HDU4336 Card Collector
有 种卡牌,每一时刻有 的概率得到其中一种,保证 ,求每种卡牌得到至少 张的期望时间。
容斥基础运用,令 表示集合 中拿到最后一张牌所需时间, 表示集合 中拿到第一张牌所需时间,有
求解。
HAOI2015 按位或
有一个数,初始为 ,每一时刻会选择一个 内的数,与该数进行或操作。选择 的概率是 ,保证 。问该数变为 的期望时间。
把数抽象成集合,容易看出是刚才那题的加强版。
令 表示集合 中拿到最后一个数被或上所需时间, 表示集合 中或上第一个数所需时间,有
求交集不为空不好弄,可以反着求交集为空的和, 时 是 补集的子集,即做一个子集求和,FWT 即可。
时间复杂度 。
P4707 重返现世
有 种元素,每一时刻有 的概率得到其中一种,保证 ,
求得到 种元素的期望时间。
一道扩展 容斥神仙题。
记 表示集合 中得到第一个元素所需时间, 表示集合 中所需时间第 大的元素,得到它的时间。因为题目给的是第 小,而这里的是第 大,为方便处理,令 ,这样 变得很小。
可以写出扩展 容斥的期望形式。
直接做复杂度爆炸,考虑对 相同的一块处理容斥系数。
记 表示由 内的若干个数组成的集合。
做一个 dp, 表示所有 且 ,参数为 时所有 之和,答案即为 。
考虑转移,当 不纳入 中时,。
若 纳入 ,则会贡献
时间复杂度 ,这里的 是新定义的。
后记
这是我第一次写这么长的博客,感觉比较典型的题里面都有了。
参考了学长的容斥原理 pdf,5 年前的 pdf 讲的很细致,感谢 dtz 学长。
只讲了一些最基础的内容,不知道能不能算是容斥原理入门。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!