组合数常用公式
C
n
m
=
n
!
(
n
−
m
)
!
∗
m
!
C_n^m=\frac{n!}{(n-m)!*m!}
Cnm=(n−m)!∗m!n!
C
n
m
=
C
n
n
−
m
C_n^m=C_n^{n-m}
Cnm=Cnn−m
C
n
m
=
C
n
−
1
m
−
1
+
C
n
−
1
m
C_n^m=C_{n-1}^{m-1}+C_{n-1}^{m}
Cnm=Cn−1m−1+Cn−1m
C
n
0
+
C
n
1
+
C
n
2
+
C
n
3
.
.
.
+
C
n
n
=
2
n
C_n^0+C_n^1+C_n^2+C_n^3...+C_n^n=2^n
Cn0+Cn1+Cn2+Cn3...+Cnn=2n
Σ
i
=
m
n
+
m
C
i
m
=
C
n
+
m
+
1
m
+
1
\Sigma_{i=m}^{n+m}C_i^m=C_{n+m+1}^{m+1}
Σi=mn+mCim=Cn+m+1m+1
(最后一个公式可以由 C m m = C m + 1 m + 1 C_m^m=C_{m+1}^{m+1} Cmm=Cm+1m+1将两项依次合并得到)
二项式定理
(
x
+
y
)
n
=
Σ
i
=
0
n
C
n
i
x
i
y
n
−
i
(x+y)^n=\Sigma_{i=0}^nC_n^ix^iy^{n-i}
(x+y)n=Σi=0nCnixiyn−i
x
i
x^i
xi的系数相当于从 n 个二项式中选出 i 个 x
推论:
Σ
i
=
0
2
∗
i
<
=
n
C
n
2
i
=
Σ
i
=
0
2
∗
i
<
n
C
n
2
i
+
1
\Sigma_{i=0}^{2*i<=n}C_n^{2i}=\Sigma_{i=0}^{2*i<n}C_n^{2i+1}
Σi=02∗i<=nCn2i=Σi=02∗i<nCn2i+1
(将
(
x
−
x
)
n
(x-x)^n
(x−x)n展开即可)
也就是说奇数项=偶数项
斯特林数
第二类斯特林数:将n个物品放入k个非空集合中的方案数,用
{
k
n
}
\{^n_k\}
{kn}来表示
常用递推公式:
考虑第一个物品是否单独放入一个集合
{
k
n
}
=
{
k
−
1
n
−
1
}
+
k
∗
{
k
n
−
1
}
\{^n_k\}=\{^{n-1}_{k-1}\}+k*\{^{n-1} _k\}
{kn}={k−1n−1}+k∗{kn−1}
初始
{
1
n
}
=
{
n
n
}
=
1
\{^n_1\}=\{^n_n\}=1
{1n}={nn}=1
(好像还有一个容斥原理的做法,但……不会卷积和反演的联赛组菜鸡选手表示放弃)
例题1 Rank
例题2 Rhyme Schemes
例题3 PushBotton Lock
第一类斯特林数
将n个物品分成k个圆排列的方案数,用
[
k
n
]
[^n_k]
[kn]来表示
常用递推公式:
[
k
n
]
=
[
k
−
1
n
−
1
]
+
[
k
n
−
1
]
∗
(
n
−
1
)
[^n_k]=[^{n-1}_{k-1}]+[^{n-1}_k]*(n-1)
[kn]=[k−1n−1]+[kn−1]∗(n−1)
初始
[
n
n
]
=
1
[_n^n]=1
[nn]=1
[
k
−
1
n
−
1
]
[^{n-1}_{k-1}]
[k−1n−1]表示将最后一个数单独创建一个圆排列的方案数
[
k
n
−
1
]
∗
(
n
−
1
)
[^{n-1}_k]*(n-1)
[kn−1]∗(n−1)表示将最后一个数插入前面k个圆排列中的方案数。对每个圆排列,能插入的位置数即为圆排列的大小,所以总的插入位置数为n-1。
例题1 Pole Arrangement
多重集的组合数
S
=
{
n
1
∗
a
1
,
n
2
∗
a
2
,
n
3
∗
a
3
,
.
.
.
,
n
k
∗
a
k
}
S=\{n1*a1,n2*a2,n3*a3,...,nk*ak\}
S={n1∗a1,n2∗a2,n3∗a3,...,nk∗ak},选择
r
(
r
≤
n
i
)
r(r\le n_i)
r(r≤ni)个数,组成的多重集的个数
a
n
s
=
C
k
+
r
−
1
k
−
1
ans=C_{k+r-1}^{k-1}
ans=Ck+r−1k−1
Lucas定理
C n m ≡ C n m o d p m m o d p ∗ C n / p m / p ( m o d P ) C_n^m \equiv C_{n\mod p}^{m\mod p}*C_{n/p}^{m/p}(\mod P) Cnm≡Cnmodpmmodp∗Cn/pm/p(modP)
ll Lucas(ll n, ll m, ll p)
{
if(m == 0)return 1;
return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
Catalan数
C
a
t
n
=
C
2
n
n
n
+
1
Cat_n=\frac{C_{2n}^{n}}{n+1}
Catn=n+1C2nn
理解:给定n个0,n个1,按照某种顺序排列为长度为2n的序列,满足任意前缀的0的个数>=1的个数
应用:
- n个左括号、n个右括号的合法匹配数 C a t n Cat_n Catn(把左括号看做0,右括号看做1)
- 1,2,……,n合法的进出栈的方案数
- n个节点形成的不同的二叉树的个数