容斥原理
搬自我的洛谷专栏。
容斥原理:
一、理论:
为什么要用容斥原理:
- 原来的条件不好做,但是反过来很好做(人们总是擅长破坏的)
怎么用容斥原理:
如果反过来正好是原条件的补集方案,那么直接用总方案减就OK了。
关键问题在于有多个条件的时候,将一个取反不是所有原条件的补集,因此需要凑配/递推容斥系数。
-
若某种方案恰好满足 \(i\) 个条件包含,设这种方案的贡献系数为 \(f(i)\)
-
若某种方案钦定满足 \(i\) 个条件 设这种方案的容斥系数为 \(g(i)\)
有:
这样可以检验你配的容斥系数是不是正确的。
比如说,非常典型的偶加奇减。
在这里,我们可以发现
我们设置的容斥系数 \(g(i)=(-1)^i\)
检验:
显然,只有\(f(0)=1\)
同样,还可以反过来递推容斥系数
根据式子:$
f(n)= \sum\limits_{i=0}^{n}{n \choose i}g(i)$
哈哈哈,以后再也不用乱凑容斥系数啦。
有了容斥系数之后,我们就可以枚举容斥的基数,然后他的贡献即为:容斥系数 $\times $ 容斥价值
附:二项式定理:
二、例题
1.devu and flowers
暴力枚举所有条件集合,钦定这些选中条件取反,加上对答案的贡献:容斥系数 * 方案贡献即可。
2.P6076 [JSOI2015] 染色问题
考虑后三个条件,先看第一个:每一行至少一个
每一行至少一个这种玩意,相当于对每一行都有限制。
至少一个不好做,但是反过来,一个没有是好说的,直接把这行删了即可,其余任意。
我们直接将所有条件取反。
但是有问题,一个条件取反后的补集并不是所有条件取反的并集,因此需要配系数。
很显然这道题的容斥系数是简单的 \((-1)^i\)
继续考虑剩下的,发现都和第一个类似。
然儿,三个条件如何合并在一起呢。
实际上,就是三种容斥相乘,因为将每个单独的容斥列成函数合并后再展开,就是乘法分配律了。
直接有以下式子:
注意在这里,我们将同一类容斥合并了,因为他们都有相同的容斥系数和容斥贡献,直接考虑他们的数量,因此出现了组合数。
3. 【COCI2009-2010#6】 XOR
这道题我们可以发现,贡献系数变了。
这咋办呢,可以先列出式子递推:
但是但是,这道题有坑,就是我们无法算出0个条件取反,就是0个三角形交的面积。
因此应该变为这样
然后就可以了,最终得出 \(g(i)=(-2)^{i-1}\)
证明:
得证。
注意此题实现的细节:
如果只存 \((x,y,r)\),会导致合并的时候出现顺序互相制约的问题:
更新r需要先更新x,y,而更新x,y又需要更新r
因此考虑直接存直线,这样就不必担心了。
4.[JSOI2011] 分特产
经典至少取反,然后容斥,不再赘述。
然后就是考虑,有 \(m\) 种小球,每种小球有 \(a_i\) 个,要分 \(n\) 个人,有多少种分发。
由于这个整体做很难,而且复杂度线性也不可能,因此考虑分步走。
我们可以发现如果分布就简单了,变为了非负整数不定方程解的个数,可以对应隔板法了。
二、“恰好与钦定”
一、理论部分:
问:为什么求恰好要用钦定。
因为有的时候,限制为恰好太困难了,因为你需要保证就这么多,不能多也不能少。
而钦定就相对简单了,你只需要满足钦定的,其余的就是随便填了。
这里说明一下钦定和至少的区别。
看起来,这俩特别像,都是兜底是多少吗。
但是差别其实很大
(一) 统计中的差别
-
钦定:先钦定再计算
-
至少:直接统计。
举个例子,集合 \({1,2,3}\)
在钦定选择两个元素的 \(f(2)\)中,{1,2,3}这个集合会被统计
因为过程是这样的,钦定1,2要选,因此多一次;钦定1,3要选,{1,2,3}有被选了一次,钦定 {1,3}要选,因此{1,2,3}被选了三次。
但是在至少有两个元素的 \(s(2)\) 中,{1,2,3}只会被统计一次,因为它的元素个数至少有两个,会被算一次,如果只有1个,那就不会在这里被统计。
(二)贡献中的差别:
如果有至少 \(i\) 个的方案数 \(s(i)\),我们就可以直接差分出来恰好 \(i\) 个的:\(s(i+1)-s(i)\)
如果有钦定 \(i\) 个的方案树 \(f(i)\),那么我们可以通过二项式反演来求,或者递推。
问:怎么用钦定求恰好
我们设共有 \(n\) 个条件
恰好满足 \(i\) 个条件的方案有 \(g(i)\)
钦定满足 \(i\) 个条件的方案有 \(f(i)\)
\(f(i)\) 一般通过dp,组合计数等技巧算出,然后反演或递推出 \(g(i)\)
二项式反演:
形式1
没见过用的,但是很好背
形式2
\(g(i)\) 表示恰好 \(i\) 个,\(f(i)\) 表示钦定只在 \(i\) 个里面选(最终选的是 \(i\) 的子集)
题目大意:
每次选一个联通块保留,删掉剩余部分,要求删掉的部分非空。问恰好删 \(k\) 次删空的方案数。
每次非空是恰好,可以不限制每次非空,这样方便很多,最后反演就好了。
形式3
用的最多,\(g(i)\) 表示恰好 \(i\) 个,\(f(i)\) 表示钦定必须选 \(i\)个(最终选的是 \(i\) 的超集)
二、例题
1.P2167 [SDOI2009] Bill的挑战
这是一道二项式计数的入门题目。
当你看到恰好的时候,应该立马反映出要用到钦定做,然后反演求恰好。
好了,考虑钦定,这是在没什么好说的,直接状态压缩,暴力枚举每种状态即可,然后算出合法的字符串数量。
算出钦定 \(i\) 个的 \(f[i]\) 后根据二项式反演,直接求出 \(g[k]\)
为什么这是一道入门题目,是因为 \(f[i]\) 的得出过程过于简单,之后,难度将加在这里。
2.P4859 已经没有什么好害怕的了
首先,推出真正的 \(k\) 即 A 有多少个数是 \(> k\)的。
和差一定,直接相加 \(/2\) 即可,得到 \(k=(n+k)/2\)
然后题目转化为了,A和B每一位匹配,A恰好有 \(k\) 位比 \(B\) 大,有多少种方案。
套路的恰好转化为钦定,然后就要考虑 \(f[i]\) 的得出了。
因为没有顺序要求,因此这种比大小问题先排个序。
设 \(f[i][j]\) 表示匹配了前 \(i\) 个,有 \(j\) 个比B中的大。
-
如果当前位没被钦定 : \(f[i][j]+=f[i-1][j]\)
-
如果当前位被钦定:我们算出他最后一个能打过的数,之前的都可以选择,设位置为 \(r\),但由于之前已经选了 \(j\) 个,因此需要扣掉这些位置,\(f[i][j]+=f[i-1][j-1] \times (r-j+1)\)
但这就完了吗?绝对没有,钦定的含义是:钦定几个,其余任意。
最后要补上任意带来的贡献,也就是说,钦定了几个后,剩余的摆放位置都是任意的,因此要有 \(f[n][j] \times = (n-j)!\)
3.P6478 [NOI Online #2 提高组] 游戏
本题难点已经转移为了如何dp了。
首先我们可以抽象题意:恰好有 \(k\) 组分出胜负的方案数。
然后套路的恰好转为钦定,然后考虑求出 \(f[i]\)
设 \(f[u][j]\) 表示以 \(u\) 为根的子树中,钦定有\(j\)轮决出胜负的方案数。
首先先忽略根对答案的影响,考虑子树贡献。
容易发现可以子树合并,这里有一点就是开一个辅助数组可以很好的解决循环顺序的问题,根本不必担心。
具体的,先将合并后的答案存入 \(tmp[]\) 中,之后再放回来即可。
最后考虑根的贡献,如果不钦定根,那就是子树合并的结果,如果钦定根:
-
如果他是白点,他可以和子树中的黑点匹配,但注意,这些点之前已经有被用过的了。
-
如果他是黑点,同理。
有转移 \(f[u][j+1]+=f[u][j] \times sz[u][c[u]\oplus1]-j)\)
其中 \(sz[u][1/0]\) 表示 \(u\) 为根的字数内黑点或百点的个数。
注意,这样转移是 \(O(n^3)\) 的,需要卡一下钦定数量上界。
可以发现,即为 \(min(sz[u][0],sz[u][1])\),这样就可以保证复杂度 \(O(n^2)\) 了

浙公网安备 33010602011771号