post on
31 Jan 2019
about
4438words
require
15min
CC BY 4.0
(除特别声明或转载文章外)
如果这篇文章帮助到你,可以请我喝一杯咖啡~
组合数取模
使用示例
为方便,记C(n,m)=Cnm=(mn)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| struct Factorial : Mod
{
vector<ll> fac, ifac;
Factorial(int N, ll M) : fac(N, 1), ifac(N, 1), Mod(M)
{
for (int i = 2; i < N; ++i)
fac[i] = mul(fac[i - 1], i), ifac[i] = mul(M - M / i, ifac[M % i]);
for (int i = 2; i < N; ++i)
ifac[i] = mul(ifac[i], ifac[i - 1]);
}
ll c(int n, int m) { return mul(mul(fac[n], ifac[m]), ifac[n - m]); }
ll lucas(ll n, ll m) //卢卡斯定理求C(n,m)%M,适用于模数M小于N的情况,或者m较小的时候也可以暴力求
{
if (!m)
return 1;
if (n < m || n % M < m % M)
return 0;
if (n < M && m < M)
return c(n, m);
return mul(lucas(n / M, m / M), lucas(n % M, m % M));
}
};
|
组合数 LCM
(n+1)lcm(C(n,0),C(n,1),…,C(n,k))=lcm(n+1,n,n−1,n−2,…,n−k+1)
区间 lcm 的维护:对于一个数,将其分解质因数,若有因子pk,那么拆分出 k 个数 p1,p2,…,pk,权值都为 p,那么区间[l,r]内所有数的 lcm 的答案=所有在该区间中出现过的数的权值之积,可持久化线段树维护之。
Stirling 数
第一类斯特林数
第一类斯特林数S(p,k)的一个的组合学解释是:将 p 个物体排成 k 个非空循环排列的方法数。
递推公式:S(p,k)=(p−1)S(p−1,k)+S(p−1,k−1),1≤k≤p−1;S(p,0)=0,p≥1;S(p,p)=1,p≥0
第二类斯特林数
第二类斯特林数S(p,k)的一个的组合学解释是:将 p 个物体划分成 k 个非空不可辨别的(可以理解为盒子没有编号)集合的方法数。
递推公式:S(p,k)=kS(p−1,k)+S(p−1,k−1),1≤k≤p−1;S(p,0)=0,p≥1;S(p,p)=1,p≥0
卷积形式:S(n,m)=m!1∑k=0m(−1)kC(m,k)(m−k)n=∑k=0mk!(−1)k(m−k)!(m−k)n
同时有转化:xk=∑i=1ki!C(x,i)S(k,i)
斯特林近似公式
n!≈2πn(en)n
小球入盒模型通解
k 个球 |
m 个盒子 |
空盒子 |
方案数 |
各不相同 |
各不相同 |
允许 |
mk |
各不相同 |
各不相同 |
无 |
m!Stirling2(k,m) |
各不相同 |
完全相同 |
允许 |
∑i=1mStirling2(k,i) |
各不相同 |
完全相同 |
无 |
Stirling2(k,m) |
完全相同 |
各不相同 |
允许 |
C(m+k−1,k) |
完全相同 |
各不相同 |
无 |
C(k−1,m−1) |
完全相同 |
完全相同 |
允许 |
(1−x)(1−x2)…(1−xm)1的xk项的系数 |
完全相同 |
完全相同 |
无 |
(1−x)(1−x2)…(1−xm)xm的xk项的系数 |
置换
使用示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| struct Permutation : vector<int>
{
Permutation(int n = 0) : vector<int>(n) {}
friend Permutation operator*(const Permutation &f, const Permutation &g)
{
Permutation ans(f.size());
for (int i = 0; i < f.size(); ++i)
ans[i] = g[f[i]];
return ans;
}
friend Permutation inv(const Permutation &f)
{
Permutation ans(f.size());
for (int i = 0; i < f.size(); ++i)
ans[f[i]] = i;
return ans;
}
friend vector<vector<int>> cycle(const Permutation &f)
{
vector<int> vis(f.size(), 0);
vector<vector<int>> ans;
for (int i = 0; i < f.size(); ++i)
if (!vis[i])
{
ans.push_back(vector<int>());
for (int j = i; !vis[j]; j = f[j])
vis[j] = 1, ans.back().push_back(j);
}
return ans;
}
};
|
生成字典序
下一排列
对给定的排列a1a2…an,找到aj使得aj<aj+1,aj+1>aj+2>⋯>an即这列数中最后一个相邻递增数对,然后把aj+1,aj+2,…,an中大于aj的最小数放到位置 j,然后aj…an中剩余的数从小到大排序放到[j+1,n]中。
1
2
3
4
5
6
7
8
9
10
11
| bool nextPermutation(ll *b, ll *e) //标准库有这个函数next_permutation
{
ll *i = e - 1, *j = e - 2;
while (j >= b && *j >= *(j + 1))
--j;
if (j < b)
return 0;
while (*i <= *j)
--i;
return swap(*i, *j), reverse(j + 1, e), 1;
}
|
二项式反演
f(n)=∑k=0nC(n,k)g(k),g(n)=∑k=0n(−1)n−kC(n,k)f(k)
第 k 小期望
f(n,k)表示有 n 个变量,和为 1,第 k 小的期望。
f(n,k)=n21+(1−n1)f(n−1,k−1),f(n,0)=0
错排数
考虑一个有 n 个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排
列的一个错排。
n 个元素的错排数Dn满足递推公式:D1=0,D2=1,Dn=(n−1)(Dn−2+Dn−1)
通项:D(n)=n![2!(−1)2+⋯+(n−1)!(−1)n−1+n!(−1)n]=⌊en!+21⌋
Bonuli 数
使用示例
Bn=−C(n+1,n)1(C(n+1,0)B0+C(n+1,1)B1+⋯+C(n+1,n−1)Bn−1)=−n+11(C(n+1,0)B0+C(n+1,1)B1+⋯+C(n+1,n−1)Bn−1)
可用于计算任意正整数次数的幂和:∑i=1nik=k+11∑j=0kC(k+1,j)Bjnk+1−j
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| struct Bonuli : Factorial
{
vector<ll> b;
Bonuli(int N, ll M) : Factorial(N, M), b(N, 0)
{
for (int i = b[0] = 1; i < N; ++i)
{
for (int j = 0; j < i; ++j)
b[i] = qadd(b[i], mul(b[j], c(i + 1, j)));
b[i] = qadd(M, -mul(b[i], mul(fac[i], ifac[i + 1])));
}
}
ll ask(ll n, int k)
{
ll r = 0, w = 1, u = add(n, 1);
for (int i = 1; i <= k + 1; ++i)
r = qadd(r, mul(mul(b[k + 1 - i], c(k + 1, i)), w = mul(w, u)));
return mul(r, mul(fac[k], ifac[k + 1]));
}
};
|
Catalan 数
h1=1,hn=n+14n−2hn−1=n+1C(2n,n)=C(2n,n)−C(2n,n−1)。
在一个格点阵列中,从(0,0)点走到(n,m)点且不经过对角线x=y的方法数:C(n+m−1,m)−C(n+m−1,m−1),x>y;C(n+m,m)−C(n+m,m−1),x≥y。
常见的 Catalan 数:括号序的个数、凸多边形三角剖分的方案数等。
Bell 数
把 n 个带标号的物品划分为若干不相交集合的方案数称为贝尔数,其递推公式:Bn=∑i=0N−1Cn−1iBi
前几项贝尔数:
1,2,5,15,52,203,877,4140,21147,115975,678570,4213597,27644437,190899322,1382958545,...
等价类容斥
考虑容斥,Bell(p)枚举所有等价情况。对于一种情况,强制了一个等价类里面的数都要相同,其它的可以相同也可以不同。
容斥系数为:(−1)p−等价类个数(每个等价类大小−1)!之积。
Grey 码
格雷序列第 i 个是i^(i>>1)
。长为 n 的 01 序列共2n个,下标从0…2n−1。
扩展 Cayley 公式
对于 n 个点,m 个连通块的图,假设每个连通块有 a[i]个点,那么用 s−1 条边把它连通的方案数为ns−2a[1]a[2]…a[m]。
超立方体
n 维超立方体有2n−iC(n,i)个 i 维元素。
枚举位集 I 的非空子集 J
1
| for(J=I; J; J=I&J−1) {}
|