错排
- 问题引入
对于有 n n n个标号为 1 ∼ n 1\sim n 1∼n的箱子和 n n n个标号为 1 ∼ n 1\sim n 1∼n的球,现在需要统计将所有的球放入箱子,每个箱子必须有且只有一个球,并且每个球的编号和装它的箱子的编号不一样的方案数。
假如 n = 3 n=3 n=3,那么所有情况如下:
[
1
]
(
2
)
[
2
]
(
3
)
[
3
]
(
1
)
[1](2)\ [2](3)\ [3](1)
[1](2) [2](3) [3](1)
[
1
]
(
3
)
[
2
]
(
1
)
[
3
]
(
2
)
[1](3)\ [2](1)\ [3](2)
[1](3) [2](1) [3](2)
方括号为箱子,圆括号为球,数字为编号。
我们可以用递推的方式求出方案数。我们令 f [ i ] f[i] f[i]表示当 n = i n=i n=i的时候的答案,那么我们新加入一个箱子和球,就有两种情况:
-
我们从原来的方案中拿出一个编号的箱子和球,有 i − 1 i-1 i−1种拿法,与这个新加入的交换,那么剩下的 i − 2 i-2 i−2个又成为了一个子问题,所以 ( i − 1 ) × f [ i − 2 ] (i-1)\times f[i-2] (i−1)×f[i−2]的贡献。
-
我们还可以从原来的里面拿出一个编号的箱子(不拿球),那么有 i − 1 i-1 i−1种拿法,然后将新的装在这个箱子里,将新的箱子和剩下的又成为一个子问题,所以有 ( i − 1 ) × f [ i − 1 ] (i-1)\times f[i-1] (i−1)×f[i−1]的贡献。
总的来说,我们就得到了递推式:
f
[
i
]
=
(
i
−
1
)
×
(
f
[
i
−
1
]
+
f
[
i
−
2
]
)
f[i]=(i-1)\times(f[i-1]+f[i-2])
f[i]=(i−1)×(f[i−1]+f[i−2])
其中边界条件为
f
[
0
]
=
1
f[0]=1
f[0]=1
在百度百科的讲解中,利用容斥原理可以得到通项公式如下:
f
[
n
]
=
n
!
×
(
∑
i
=
0
n
1
i
!
×
(
−
1
)
i
)
f[n]=n!\times\left(\sum\limits_{i=0}^n\frac{1}{i!}\times(-1)^{i}\right)
f[n]=n!×(i=0∑ni!1×(−1)i)
例题:
【IN Luogu】
本题是 I m a g i n e \rm Imagine Imagine大佬出的,在此 O r z \rm Orz Orz并感谢他的讲解。
我们先算出刚好 K K K个配对的方案数量,然后乘以剩下的错排方案数,但是这个显然不是简单的错排了,因此不能直接套用公式。
前面的刚好 K K K个配对的就是:
- 选 k k k排座位 C n k C_n^k Cnk
- 选 k k k对情侣 C n k C_n^k Cnk
- 这 k k k对每排可以交换坐 2 k 2^k 2k
- 这 k k k排可以任意排列 k ! k! k!
所以前半部分的答案就为 ( C n k ) 2 × k ! × 2 k (C_n^k)^2\times k!\times 2^k (Cnk)2×k!×2k
那么对于错排部分,我们模仿错排递推的推导过程分类考虑,我们令 g [ n ] g[n] g[n]为 n n n对不匹配的方案数:
首先第一排坐两个不是情侣的人,不难发现那么可以有 2 n × ( 2 n − 2 ) 2n\times (2n-2) 2n×(2n−2)种选法,剩下只有 n − 1 n-1 n−1个座位,对于剩下的,我们考虑另外的两个就是与开始那两个坐在一起的另一半情侣,他们有两种方案:
- 坐在一起:就是在剩下的 n − 1 n-1 n−1排中任选一排,且这个两个人可以交换,然后就转化为子问题 g [ n − 2 ] g[n-2] g[n−2],所以贡献为 2 × ( n − 1 ) × g [ n − 2 ] 2\times (n-1)\times g[n-2] 2×(n−1)×g[n−2]
- 不坐在一起,我们就把他们又看作一个不能在一起的错排问题,于是贡献为 g [ n − 1 ] g[n-1] g[n−1]
和错排公式结合起来,所以这部分的方案数贡献为 2 n ( 2 n − 2 ) ( g [ n − 1 ] + 2 ( n − 1 ) g [ n − 2 ] ) 2n(2n-2)\left(g[n-1]+2(n-1)g[n-2]\right) 2n(2n−2)(g[n−1]+2(n−1)g[n−2])
那么答案就是 ( C n k ) 2 × k ! × 2 k × 4 n ( n − 1 ) ( g [ n − 1 ] + 2 ( n − 1 ) g [ n − 2 ] ) (C_n^k)^2\times k!\times 2^k\times 4n(n-1)\left(g[n-1]+2(n-1)g[n-2]\right) (Cnk)2×k!×2k×4n(n−1)(g[n−1]+2(n−1)g[n−2])
预处理阶乘和阶乘逆元还有 g g g函数,然后每次 O ( 1 ) O(1) O(1)的回答即可。
复杂度为 O ( l o g M o d + n + T ) O(logMod+n+T) O(logMod+n+T)