浅谈容斥
前言
\(2020.2.12\),太久没碰过容斥原理的我,由第一类斯特林发现容斥原理还有较多细节未完善,故写了这篇文章,从最基础的讲起,以方便理解
定义
例子
- 求从\(1\)到\(1000\)之间不能被\(5,6,8\)整除的整数个数
\(|\overline{A_1}\cap \overline{A_2}\cap \overline{A_3}|\)分别不能被\(5,6,8\)整除的数交\(=1000-(|A_1|+|A_2|+|A_3|-|A_1\cup A_2|-|A_1\cup A_3|-|A_2\cup A_3|+|A_1\cup A_2\cup A_3|)\)
分析:补集为至少能被一个数整除,减掉分别能被\(5,6,8\)整除的数,但能同时被两个以上的数整除的数被重复减掉了
例题
- CF1060F
题意:给定一棵\(n\)阶树T。当\(|T|>1\)时,反复执行:
\((1)\)等概率选择\(T\)中一条边
\((2)\)收缩选取的边:即合并。得到的新点的编号等概率从该边\((u,v)\)中选取。
当\(|T|=1\),它的编号可能是\([1,n]\)中任意一个数。求对于每个编号,其成为最终点的概率。
做法:
转化题意:初始树上没有边,每个节点权值为\(1\),随机一个边集排列,依次加入边,加入这条边时将这条边所连接的两个连通块所有点权值\(\times \frac{1}{2}\)。最后每个的期望权值。
枚举节点\(rt\),单独计算该点期望。
\((rt,v)\)的边会让\(rt\)的权值\(\times \frac{1}{2}\)。\((rt,v)\)加入时,\(v\)会在某个连通块\(S\)中。
\(e\in\{(p,q)|p\in S\land q\in S\land (p,q)\in E\}\),会在\((rt,v)\)之前加入
\(e\in\{(p,q)|p\in S\land q\notin S\land (p,q)\in E\}\),会在\((rt,v)\)后加入,对\(rt\)产生\(\times \frac{1}{2}\)的贡献。而\(q\)又会在某个连通块内,可以递归考虑。
为方便描述,令\(e\)会让\(rt\)连通块变大(即产生\(\times \frac{1}{2}\)的贡献)的边称为主动边,反之称为被动边。
被动的产生:加入一条主动边\((p,q)\)时,\(q\)所在连通块\(S\)的边变为被动边。
考虑一张新图,新图上的点与原树的边一一对应,新图上的边有两种:
\((1)\):主动边向其产生的所有被动边连边。即\((p,q)\)向\(S\)内的所有边连边。
\((2)\):主动边向其最近的主动边祖先连边(如果存在)。只有\((rt,v)\)会没有主动边祖先。
新图与原图的主动边被动边的情况一一对应,新图的topsort与主动边被动边确定时再细分的情况一一对应。
现在考虑算topsort。所有被动边仅有产生它的主动边向它连边,而主动边的导出子图是内向树森林。加上被动边后实际上把原树良好的性质打破了,则我们容斥。
考虑容斥:被动边是否强制也向主动边一样向主动边祖先连边
被动边的\(size=1\),而主动边\((u,v)\)的\(size\)为\(v\)在原树的子树大小减去原树\(v\)子树中选择不与主动边连边的被动边数量。令\(f_{i,j}\)为\(i\)子树选择不与主动边连边的被动边数量。
code
- [CTS2019]氪金手游
题意:
\(n\)阶有向树,每个点为\(1,2,3\)的权值的概率分别为\(w_{i,1},w_{i,2},w_{i,3}\)。在玩一种不停选点的游戏,可重复选,直到选过所有点,选到点\(i\)的概率为\(\frac{w_i}{\sum\limits_{j=1}^n w_j}\),每个点第一次选到记为\(T_i\)。对于每一条树边\((u_i,v_i)\),满足\(T_{u_i}<T_{v_i}\)才合法。求合法的概率
做法:
考虑某点为根,假设这棵树为外向树,且每点的权值确定:考虑\(i\)子树的合法性,设\(S_i\)为\(i\)子树的权值和,则\(i\)比子树先抽到的概率为\(\frac{w_i}{S_i}\)
那么答案为\(\prod\limits_{i=1}^n \frac{w_i}{S_i}\)
权值不定:另开一维,\(f_{i,j}\)表示\(i\)子树合法且子树权值和为\(j\)的概率
边并非全外向:考虑对内向边容斥。
考虑一个特殊情况:链
\(1\rightarrow 2 \rightarrow\cdots\rightarrow(k-1)\leftarrow k\rightarrow(k+1)\rightarrow \cdots\rightarrow(n-1)\rightarrow n\)
\(P=P(1\rightarrow (k-1))\times P(k\rightarrow n)-P(1\rightarrow n)\)
P(内向)=P(忽略这条边)-P(外向)
扩展到树上,将容斥系数算进dp即可
具体实现code
思考:
网上对\(i\)比子树先抽到的概率为:\(\frac{w_i}{S_i}\sum\limits_{j=0}^{\infty}(\frac{sum-S_i}{sum})^j=\frac{w_i}{S_i}\)(记\(sum\)为整棵树权值和)
但把所有点的概率乘到一起,是会出现跨子树影响的问题,虽然答案并没错,但我觉得这样的解释有问题
- AGC5
题意:\(n\)排列,有多少种排列满足,\(\forall i,|a[i]-i|!=K\)
做法:\(ans=\sum_{i=0}^{n}(-1)^ig[i](n-i)!(g[i]\)表示至少有\(i\)个位置是不合法的方案数\()\)
考虑如何求\(g[i]\)
将每个位置和每个值都作为一个点,有\(2n\)个点,如果第\(i\)位置不可以填\(j\),将位置\(i\)向值\(j\)连边。
这样,就得到了一个二分图,问题就变成了选\(i\)条边的方案数。
将二分图的每条链拉出来,并在一起,就形成\(2n\)个点排成一排,一些相邻点之间有边。
\(f[i][j][0/1]\)表示,做到第\(i\)个点,选了\(j\)条边,这个点与上个一点的边是否有选(如果没边就为\(0\))的方案数。
\(g[i]=f[2n][i]][0]+f[2n][i][1]\)
- AGC35F
\(n\times m\)的方格,初始为\(0\),给每行选择一个\(a_i,0\le b_i\le m\);给每列选择一个\(0\le b_i\le n\),然后给各行前面\(a_i\)个数\(+1\),列同理。最后得到\(0,1,2\)所组成的一个方格,求不同方格的个数
做法:重复当且仅当某行某列填的东西恰好挨一起了(为相交)
则有\(ans=\sum_{i=0}^{min\{N, M\}}(-1)^iC_{N}^{i}*C_{M}^{i} *i!*(N+1)^{M-i}*(M+1)^{N-i}\)
- [THUWC2017]随机二分图
左右各\(n\)个点的二部图,\(m\)组边(每组边可能为一下三类)
\(1)(u,v)\):\((u,v)\)出现与不出现的概率为\(0.5\)
\(2)(u_1,v_1)(u_2,v_2)\):同时出现与同时不出现的概率为\(0.5\)
\(3)(u_1,v_1)(u_2,v_2)\):恰好某条边出现的概率为\(0.5\)
求期望完美匹配的个数。\(n\le 15\)
设\(f_{bit1,bit2}\)为左边点\(bit1\)还未匹配,右边\(bit2\)还未匹配,状态数为\(\sum\limits_{i=1}^n \binom{n}{i}^2\),但数据问题状态数不多
建边:
\(1)\):\((u,v,0.5)\)
\(2)\):\((u_1,v_1,0.5),(u_2,v_2,0.5)(u_1u_2,v_1v_2,0.25)\)
\(2)\):\((u_1,v_1,0.5),(u_2,v_2,0.5)(u_1u_2,v_1v_2,-0.25)\)
做法:
一种完美匹配出现的概率为边之积
解释:
只考虑出现在匹配中的概率是否满足题意
对于\(2)\),同时出现的两条边的概率为\(0.5\),只出现一条边的概率为\(0.5\)(原题意中同时出现仅选一条的概率),均不出现为\(0.5\)
对于\(3)\)同理
- 雅礼集训union
题意:
已知 n 个点,点 i 与点 j 有 C(i, j) 种不同的连边方式(这个不是组合数!)。
求最终可能的不同连通图个数。
做法:
设\(f(s)\)表示状态为\(s\)的连通图,\(g(s)\)表示集合状态为\(s\)的不需要连通的图
\(f(s)=g(s)-\sum\limits_{t\sub s}f(t)g(s-t)\)
为避免算重,强制\(f(t)\)中包含\(1\)
显然
\(\begin{aligned}g(s)=\prod_{i<j且i,j\in s}(C(i,j)+1),g(0)=0\\f'(s) = h(s) - \sum_{t\subset s}f'(t)*g'(s-t)\end{aligned}\)
注意 \(h\) 和 \(g'\) 是不一样的,前者必须要包含 \(1\) 号点,后者不能包含一号点。然后子集卷积求逆即可
- AGC36F
题意:
给定一个整数\(N\),统计有多少个\(0\sim2N-1\)的排列\(P_0,P_1,...,P_{2N-1}\)满足:\(N^2\le i^2+P_i^2\le 4N^2(0\le i<2N)\)
做法:
根据条件,可以求得\(P_i\)的上下界\(lb_i \le P_i \le rb_i\)
当\(0 \le i < N\)时,\(lb_i = \sqrt{N^2 - i^2}, rb_i = \sqrt{(2N)^2 - i^2}\)
当\(N \le i < 2N\)时,\(lb_i = 0, rb_i = \sqrt{(2N)^2 - i^2}\)
注意到\(i\ge N\)时下界已确定。
若全部的数\(lb_i\)全为\(0\),则贡献为\(\prod_{i=0}^{2N-1}(rb'_i + 1 - i)\)
然后考虑容斥,强制某些数\(P_i\le lb_i-1\),其他的数\(P_i\le rb_i\)
性质:对于\(0\sim N-1\),\(max\{lb\}\le min\{rb\}\)
由此,我们将 \(0 \sim N-1\) 以 \(lb-1\) 为第一关键字,\(rb\) 为第二关键字; \(N ~ 2N-1\) 以 \(rb\) 为第一关键字,\(0\) 为第二关键字,全部进行排序。
从小到大作 \(dp\),令 \(dp(i, j)\) 表示前 \(i\) 个选出 \(j\) 个 \(< lb\) 的方案数。最后 \(f(k) = dp(2N, k)\)。
总方案为 \(f(0) - f(1) + f(2) - f(3) + ...\)
时间复杂度 \(O(n^3)\)
- ARC93F
题意:
有\(2^N\)个人打锦标赛,他们的过程是随机一个排列,然后按照这个排列站好。每轮是第\(2i-1\)个人和\(2i\)个人比赛,败者淘汰。
你是\(1\)号选手,你碰到\(A_1,A_2,...,A_m\)会输,碰到剩下的会赢。如果比赛和你无关,那么编号小的赢。求有多少个排列,能够使你最好赢\((1\le n\le 16,0\le m\le 16,2\le A_i\le 2^N)\)
过程是一个二叉树,\(1\)的位置不重要,因为节点的两棵子树位置不重要,可以反复交换位置使\(p_1=1\)
然后\(G_i=min\{p_{2^{i}+1},...,p_{2^{i+1}}\}\)为\(1\)每轮需要比赛的人,赢的话是的\(G_i\)中没有\(A\)
考虑容斥,枚举至少有多少个在\(A\)里面,记状态为\(f_{S}\),把\(A\)从大到小排序,转移很简单
- ARC96E
题意:
求有多少个子集族,满足:
\(1)\):其中任意一个子集都是\([n]\)的子集
\(2)\):任意两个子集互不相同
\(3)\):\(1,2,...,n\)都在其中至少出现了\(2\)次
\(2\le n\le 3000\)
做法:
钦定前\([1,k]\)最终使用不超过\(1\)次的方案数\(f_k\)
\(f_k=\sum\limits_{c=0}^k \sum\limits_{i=c}^k \binom{k}{i}S2(i,c)\times 2^{2^{n-k}}2^{c(n-k)}\)
解释:枚举包含\([1,k]\)的集合个数\(c\),枚举出现了\(1\)次的数字\(k\),剩下的随便选
有个讨巧的方式是在\(k\)个数字中加入一个垃圾堆,跟垃圾堆分到一组的一次都不选,则\(f_k=\sum\limits_{c=0}^k S2(k+1,c+1)2^{2^{n-k}}2^{c(n-k)}\)
- ARC101E
题意:
给定\(N\)个点的树,你需要把这些点分到\(\frac{N}{2}\)组,每组恰好\(2\)个点,且每个点至多在一组。称一个分组方案是好的,当且仅当:如果我们把每对点的最短路上的边都打上标记,最后每条边都被标记了。求好的分组方案数。\(2\le N\le 5000,2|N\)
做法:
对至少有多少条边不经过容斥,\(f_{i,j,0/1}\)为\(i\)子树,其中\(i\)所在连通块的大小为\(j\),割边的奇偶性,然后树形背包即可
- ARC102E
题意
\(N\)个\(K\)面骰子,当\(i=2,3,4...,2k\)时,求所有骰子的点数中,没有任何两个之和为\(i\)的方案数。这\(N\)个骰子不互相区分(即\(1,2\)与\(2,1\)是同一种情况)
做法
单独考虑\(i\)。算出矛盾对数\(k2=min\{k-\lfloor \frac i 2 \rfloor,\lfloor \frac {i-1} 2 \rfloor \}\),没有影响的个数\(k1=k-k2*2-[i\%2==0]\)
枚举至少有\(j\)个对数没选
\(ans_i=\sum_{j=0}^{j\leq k2}(-1)^j C_{N+k1+k2-j-1}^{k1+k2-j-1}*2^{k2-j}*C_{k2}^j\)
- CF995F Cowmpany Cowmpensation
题意:
给定一棵\(n\)阶树,你要给每个点定一个\([1,D]\)的权值,满足每个点权值不大于父亲。问有多少种方案。\(n\le 3000,D\le 10^9\)
做法:
\(f_{u,j}\)为\(u\)选择值\(j\)的子树方案数,\(g_{u,j}=\sum\limits_{i=1}^j f_{u,i}\)。
有\(f_{u,j}=\prod\limits_{v\in son}g_{v,j}\)
显然是不能把\(D\)存到第二维的,但整棵数实际用到的权值种数不超过\(n\)
设\(G(i)\)为整棵树恰好用了\(i\)种权值的方案数
\(ans=\sum\limits_{i=1}^{min(n,d)}{d \choose i}G(i)\)
\(G(i)=f_{1,i}-\sum\limits_{j=1}^{i-1}{i \choose j}G(j)\)
- 【GDOI2020模拟02.19】A
题意:
给出\(D\),数字集合\(T\),\(0\le T_i< D\)
对满足下列条件的正整数序列\(A_1,A_2,...,A_n\)进行计数,对\(1e9+7\)取模
\((1):\forall 1\le i\le n,L_i\le A_i\le R_i\)
\((2):\)令\(S=\sum A_i\),满足\(S\)的\(D\)进制拆分中的数字去掉前导\(0\)
\(n\le 12,D\le 500,1\le L_i\le R_i\le D^{500}\)
做法:
\(n\)较小,考虑对下界容斥,也就是强制某些位小于\(L_i\),相当于\(\le L_i-1\),我们先将\(L_i\)直接赋为\(L_i-1\)
设\(S\)为所有下界之和,假设总和为\(V\),显然方案数为\({V-S-1\choose n-1}\),为了方便,再让\(S+1\)
\(\sum\limits_{V=S}^{\infty}{V-S\choose n-1}[V合法]=\sum\limits_{V=S}^{\infty}\sum\limits_{i=0}^{n-1}{V\choose i}{-S\choose n-1-i}[V合法]=\sum\limits_{i=0}^{n-1}{-S\choose n-1-i}\sum\limits_{V=S}^{\infty}{V\choose i}[V合法]\)
进一步地,\({V\choose i}\)也用范德蒙德恒等式转移
code
题意:
给定两个长度为 (n) 的数组 (a,b)。
要求给一个 (n×n) 的矩阵的每个位置填上一个非负整数,使得第 (i) 行的最大值为 (a_i),第 (j) 列的最大值为 (b_j)。
求方案数对 (998244353) 取模的结果。
做法:
显然可以把\(a,b\)分别降序排序,不影响结果。
记 \(c_{i,j}=min(a_i,b_j)\)。考虑将 \(c_{i,j}\)相同的位置放在一起处理。
相同的位置会形成一个类似\(L\)形,\(a_{x_1}\sim a_{x_2},b_{y_1}\sim b_{y_2}=s\)
那么对于这个\(L\)形的填数,满足:
\((1)\):每个格子的数为\([0,s]\)
\((2)\):第\(x_1\sim x_2\)行的最大值为\(s\)
\((3)\):第\(y_1\sim y_2\)列的最大值为\(s\)
考虑容斥,设\(f(i)\)为第\(x_1\sim x_2\)行中,至少有\(i\)行的最大值不是\(s\)的方案数(需要保证\(y_1\sim y_2\)列的最大值为\(s\))
令\(l_x=x_2-x_1+1,l_y=y_2-y_1+1\),则\(ans=\sum\limits_{i=0}^{lx} (-1)^i f(i)\)
\(f(i)={l_x\choose i}s^{i*y_2}\times ((s+1)^{x_2-i}-s^{x_2-i})^{l_y}\times(s+1)^{(l_x-i)(y_1-1)}\)