容斥原理+错排问题
容斥原理+错排问题
1. 一般形式
设全集 \(S\) 中的元素共有 \(n\) 种性质,每一个元素可以有多种性质。
我们把具有第 \(i\) 种性质的元素全部放到集合 \(A_i\) 中,生成 \(A_1,A_2,A_3,\cdots,A_n\)。它们都是 \(S\) 的子集。
如果我们要对 至少满足一个性质 的元素计数,那么答案为:
-
Proof:我们考虑 \(S\) 中的每一个元素对等式右边贡献了多少。
如果元素 \(x\) 不满足满足所有性质,显然 \(x\) 不会对等式右边造成任何贡献。
如果元素 \(x\) 满足 \(m\) 个性质 ,那么当 \(|J|=k\) 时,会对等式右边贡献 \((-1)^{k-1}\binom{m}{k}\)。
那么这个 \(x\) 对等式右边总共贡献了:
\[\sum_{k=1}^m (-1)^{k-1}\binom{m}{k}=-\sum_{k=0}^m (-1)^{k}\binom{m}{k}+1=0+1=1 \]故等式成立。
如果我们要对 不满足任何一个性质 的元素计数,答案为:
同理可证。也可以用摩根定律由第一种形式转化而来:并集的补等于补集的交。
2. 与二项式系数
如果 \(\left| \bigcap_{i\in J}A_i \right|\) 的值只与 \(|J|\) 有关,那么我们设 \(a_k\) 为 \(|J|=k\) 时 \(\left| \bigcap_{i\in J}A_i \right|\) 的值,那么容斥原理的形式可以简化为:
3. 错排问题
对满足以下条件的 排列 \(A\) 计数:
- 长度为 \(n\);
- 对于所有在 \([1,n]\) 内的整数 \(i\),\(A_i\ne i\)。
我们称这样的排列 \(A\) 的个数为 错排数,记为 \(D_n\)。
特别地,\(D_0=1,D_1=0\)。
i. 通项式
如果在排列 \(A\) 中有 \(k\) 个位置不满足 \(A_i\ne i\),设它们为 \(i_1,i_2,\cdots,i_k\),那么这些位置的值都固定为 \(A_{i_j}=i_j\)。
而剩下位置有 \((n-k)!\) 种排列方式,由乘法原理,得 \(a_k=(n-k)!\)。
由容斥原理,得
ii. 递推式 I
考虑排列 \(A\) 中 \(1\) 的位置。显然,\(1\) 可能的位置有 \(n-1\) 种。
设 \(A_k=1\),分两种情况讨论:
- \(A_1=k\),剩下 \(n-2\) 个元素构成了规模为 \(n-2\) 的子问题,答案为 \(D_{n-2}\);
- \(A_1\ne k\),相当于 \(k\) 的限制由 \(A_k\ne k\) 变为 \(A_1\ne k\),\(k\) 与剩下 \(n-2\) 个元素构成了规模为 \((n-1)\) 的子问题,答案为 \(D_{n-1}\)。
由乘法原理,\(D_n=(n-1)(D_{n-1}+D_{n-2})\)。
iii. 递推式 II
最终得到:
iv. 与自然常数
\(e^{-1}\) 的无穷级数展开式:
随机生成一个长度为 \(n\) 的排列 \(A\),其为一个错排的概率为:
则有:
v. 与全排列
4. 相对错排问题
对满足以下条件的 排列 \(A\) 计数:
- 长度为 \(n\);
- 对于所有在 \((1,n]\) 中的整数 \(i\),满足 \(A_{i-1}\ne A_i-1\)。
我们称这样的排列 \(A\) 的个数为 相对错排数,记为 \(Q_n\)。
i. 通项式
设 \(i_1,i_2,\cdots,i_k\) 这些数字不满足条件。
此时,对于每一个 \(i_j\),我们把 \(i_j\) 与 \(i_j-1\) 合并为一个符号。合并 \(k\) 次,排列中还剩下 \(n-k\) 个符号。那么 \(a_k=(n-k)!\)。
由容斥原理,得
ii. 递推式
Proof
引理:
然后有:
5. 部分错排问题
对满足以下条件的 排列 \(A\) 计数:
- 长度为 $n+m $;
- 对于任意在 $[1,m] $ 中的整数 \(i\),\(A_i\ne i\)。
也就是排列中有 \(n\) 个自由元素,\(m\) 个限制元素。
我们称这样的排列 \(A\) 的个数为 部分错排数,记为 \(B_{n,m}\)。
Version I
给出一组 \(n,m\) 求 \(B_{n,m}\),其中 \(0\leq n,m\leq 10^6\)。
根据容斥原理,答案即为
Version II
对所有 \(n,m\) 求 \(B_{n,m}\),其中 \(0\leq n,m \leq 2000\)。
首先有 \(B_{n,0}=n!,B_{0,m}=D_m\)。
对于其他情况,考虑 \(A_{n+m}\) 填什么。记 \(A_{n+m}=k\),分情况讨论:
- \(1\leq k\leq m\)。此时 \(A_k\ne k\) 这个限制不再生效,那么 \(A_k\) 填什么数字不再有限制。则在前 \(n+m-1\) 个位置中,还有 \(m-1\) 个位置有限制,\(n\) 个位置没限制,贡献为 \(m\times B_{n,m-1}\);
- \(m<k\leq m+n\)。这对于所有的 $ A_i\ne i$ 的限制没有任何影响。则在前 \(n+m-1\) 个位置中,还有 \(m\) 个位置有限制,\(n-1\) 个位置没限制,贡献为 \(n\times B_{n-1,m}\)。
于是得出递推式 1:
还有一种考虑方式:
- \(k=n+m\)。显然贡献为 \(B_{n-1,m}\);
- \(k\neq n+m\)。此时增加了一个 \(A_{n+m}\ne n+m\) 的限制,那么 \(n+m\) 变得有限制,贡献为 \(B_{n-1,m+1}\);
得到递推式 2:\(B_{n,m}=B_{n-1,m}+B_{n-1,m+1}\)。
Version III
\(n\) 固定,对所有的 $ m$ 求 \(B_{n,m}\),其中 \(1\leq n \leq 10^7,1\leq m \leq 10^5\)。
首先有 \(B_{n,0}=n!\),\(B_{n,1}=n\times n!\)。
当 \(m\geq 2\) 时,考虑 \(A_m\) 填什么。记 \(A_m=k\),分情况讨论:
- \(1\leq k \leq m\)。类似于 \(D_n\) 的递推式 I,贡献为 \((m-1)(B_{n,m-1}+B_{n,m-2})\);
- \(m<k\leq m+n\)。此时 \(A_m\) 这个位置没有限制,那么还剩下 \(m-1\) 个位置有限制,贡献为 \(n\times B_{n,m-1}\)。
于是得出递推式 3:
Version IV
\(Q\) 组询问,每次询问一个 \(B_{n,m}\) 的值,\(1\leq n,m,Q\leq 10^5\)。
假如我们已经知道 \(B_{n,m},B_{n,m+1}\) 的值。
由递推式 3,可以直接求出 \(B_{n,m-1},B_{n,m+2}\):
由递推式 1,
由递推式 2,
联立递推式 1,2,
我们可以 \(O(1)\) 求出 \((n,m),(n,m+1)\) 相邻 \(6\) 个位置的值,那么我们就可以 \(O(1)\) 地移动 \(n\) 或 \(m\)。
将所有询问离线后莫队求解。复杂度 \(O(N\sqrt{Q})\),其中 \(N=\max(n_i,m_i)\)。
这种 trick 也叫作 局部递推,即列出若干个线性无关方程组实现参数的微调。

浙公网安备 33010602011771号