为方便,记 C ( n , m ) = C n m = ( n m ) C(n,m)=C_n^m=\binom{n}{m} C(n,m)=Cnm=(mn)。
struct Factorial//预处理阶乘及对应的逆元
{
vector fac,ifac;
ll M;
Factorial(int N,ll M):fac(N,1),ifac(N,1),M(M)
{
for(int i=2; i
( n + 1 ) l c m ( C ( n , 0 ) , C ( n , 1 ) , … , C ( n , k ) ) = l c m ( n + 1 , n , n − 1 , n − 2 , … , n − k + 1 ) (n + 1)lcm(C(n,0),C(n,1),\ldots,C(n,k))=lcm(n+1,n,n−1,n−2,\ldots,n−k+1) (n+1)lcm(C(n,0),C(n,1),…,C(n,k))=lcm(n+1,n,n−1,n−2,…,n−k+1)
对于一个数,将其分解质因数,若有因子 p k p^k pk,那么拆分出k个数 p 1 , p 2 , … , p k p^1,p^2,\ldots,p^k p1,p2,…,pk,权值都为p,那么区间 [ l , r ] [l,r] [l,r]内所有数的lcm的答案=所有在该区间中出现过的数的权值之积,可持久化线段树维护之。
第一类斯特林数 S ( p , k ) S(p,k) 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−1)S(p−1,k)+S(p−1,k−1),1\leq k\leq p−1;S(p,0) = 0,p\ge1;S(p,p) = 1,p\ge0 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 ) S(p,k) S(p,k)的一个的组合学解释是:将p个物体划分成k个非空不可辨别的(可以理解为盒子没有编号)集合的方法数。
递推公式: S ( p , k ) = k 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) = kS(p−1,k) + S(p−1,k−1),1\leq k\leq p−1;S(p,0) = 0,p\ge 1;S(p,p) = 1,p\ge0 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 ) = 1 m ! ∑ k = 0 m ( − 1 ) k C ( m , k ) ( m − k ) n = ∑ k = 0 m ( − 1 ) k k ! ( m − k ) n ( m − k ) ! S(n,m)=\frac{1}{m!}\sum_{k=0}^m (-1)^kC(m,k)(m-k)^n=\sum_{k=0}^m\frac{(-1)^k}{k!}\frac{(m-k)^n}{(m-k)!} S(n,m)=m!1∑k=0m(−1)kC(m,k)(m−k)n=∑k=0mk!(−1)k(m−k)!(m−k)n
同时有转化: x k = ∑ i = 1 k i ! C ( x , i ) S ( k , i ) x^k=\sum_{i=1}^ki!C(x,i)S(k,i) xk=∑i=1ki!C(x,i)S(k,i)
n ! ≈ 2 π n ( n e ) n n!\approx\sqrt{2πn}(\frac{n}{e})^n n!≈2πn(en)n
k 个球 | m个盒子 | 空盒子 | 方案数 |
---|---|---|---|
各不相同 | 各不相同 | 允许 | m k m^k mk |
各不相同 | 各不相同 | 无 | m ! S t i r l i n g 2 ( k , m ) m!Stirling2(k,m) m!Stirling2(k,m) |
各不相同 | 完全相同 | 允许 | ∑ i = 1 m S t i r l i n g 2 ( k , i ) \sum_{i=1}^mStirling2(k,i) ∑i=1mStirling2(k,i) |
各不相同 | 完全相同 | 无 | S t i r l i n g 2 ( k , m ) Stirling2(k,m) Stirling2(k,m) |
完全相同 | 各不相同 | 允许 | C ( m + k − 1 , k ) C(m+k−1,k) C(m+k−1,k) |
完全相同 | 各不相同 | 无 | C ( k − 1 , m − 1 ) C(k−1,m−1) C(k−1,m−1) |
完全相同 | 完全相同 | 允许 | 1 ( 1 − x ) ( 1 − x 2 ) . . . ( 1 − x m ) 的 x k 项 的 系 数 \frac{1}{(1−x)(1−x^2)...(1−x^m)}的x^k项的系数 (1−x)(1−x2)...(1−xm)1的xk项的系数 |
完全相同 | 完全相同 | 无 | x m ( 1 − x ) ( 1 − x 2 ) . . . ( 1 − x m ) 的 x k 项 的 系 数 \frac{x^m}{(1−x)(1−x^2)...(1−x^m)}的x^k项的系数 (1−x)(1−x2)...(1−xm)xm的xk项的系数 |
struct Permutation:vector
{
Permutation(int n=0):vector(n) {}
friend Permutation operator*(const Permutation &f,const Permutation &g)
{
Permutation ans(f.size());
for(int i=0; i > cycle(const Permutation &f)
{
vector vis(f.size(),0);
vector > ans;
for(int i=0; i());
for(int j=i; !vis[j]; j=f[j])
{
vis[j]=1;
ans.back().push_back(j);
}
}
return ans;
}
};
对给定的排列 a 1 a 2 … a n a_1a_2\ldots a_n a1a2…an,找到 a j a_j aj使得 a j < a j + 1 , a j + 1 > a j + 2 > … > a n a_j<a_{j+1},a_{j+1}>a_{j+2}>\ldots>a_n aj<aj+1,aj+1>aj+2>…>an即这列数中最后一个相邻递增数对,然后把 a j + 1 , a j + 2 , … , a n a_{j+1},a_{j+2},\ldots,a_n aj+1,aj+2,…,an中大于 a j a_j aj的最小数放到位置j,然后 a j … a n a_j\ldots a_n aj…an中剩余的数从小到大排序放到 [ j + 1 , n ] [j+1,n] [j+1,n]中。
bool nextPermutation(ll *b,ll *e)//标准库有这个函数next_permutation
{
ll *i=e-1,*j=e-2;
while(j>=b&&*j>=*(j+1))--j;
if(j
//待填坑
枚举i的非空子集j。
for(j=i; j; j=i&j−1) {}
这些函数都有相应的usigned long
和usigned long long
版本,只需要在函数名后面加上l
或ll
就可以了,比如__builtin_clzll
.
int __builtin_clz(unsigned int x);//求前缀0的个数
int __builtin_ctz(unsigned int x);//求后缀0的个数
int __builtin_ffs(unsigned int x);//x的二进制末尾最后一个1的位置,从1开始
int __builtin_popcount(unsigned int x);//x二进制中1的个数,相当于bitset::count()
int __builtin_parity(unsigned int x);//判断x的二进制中1的个数的奇(1)偶(0)性
f ( n ) = ∑ k = 0 n C ( n , k ) g ( k ) , g ( n ) = ∑ k = 0 n ( − 1 ) n − k C ( n , k ) f ( k ) f(n)=\sum_{k=0}^nC(n,k)g(k),g(n)=\sum_{k=0}^n(−1)^{n−k}C(n,k)f(k) f(n)=∑k=0nC(n,k)g(k),g(n)=∑k=0n(−1)n−kC(n,k)f(k)
f ( n , k ) f(n,k) f(n,k) 表示有n个变量,和为1,第k小的期望。
f ( n , k ) = 1 n 2 + ( 1 − 1 n ) f ( n − 1 , k − 1 ) , f ( n , 0 ) = 0 f(n,k)=\frac{1}{n^2}+(1-\frac{1}{n})f(n-1,k-1),f(n,0)=0 f(n,k)=n21+(1−n1)f(n−1,k−1),f(n,0)=0
考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。
n个元素的错排数 D n D_n Dn满足递推公式: D 1 = 0 , D 2 = 1 , D n = ( n − 1 ) ( D n − 2 + D n − 1 ) D_1=0,D_2=1,D_n=(n−1)(D_{n−2}+D_{n−1}) D1=0,D2=1,Dn=(n−1)(Dn−2+Dn−1)
通项: D ( n ) = n ! [ ( − 1 ) 2 2 ! + … + ( − 1 ) n − 1 ( n − 1 ) ! + ( − 1 ) n n ! ] = ⌊ n ! e + 1 2 ⌋ D(n)=n![\frac{(-1)^2}{2!}+\ldots+\frac{(-1)^{n-1}}{(n-1)!}+\frac{(-1)^n}{n!}]=\lfloor\frac{n!}{e}+\frac{1}{2}\rfloor D(n)=n![2!(−1)2+…+(n−1)!(−1)n−1+n!(−1)n]=⌊en!+21⌋
B n = − 1 C ( n + 1 , n ) ( C ( n + 1 , 0 ) B 0 + C ( n + 1 , 1 ) B 1 + … + C ( n + 1 , n − 1 ) B n − 1 ) = − 1 n + 1 ( C ( n + 1 , 0 ) B 0 + C ( n + 1 , 1 ) B 1 + … + C ( n + 1 , n − 1 ) B n − 1 ) B_n = -\frac{1}{C(n+1,n)}(C(n+1,0)B_0+C(n+1,1)B_1+\ldots+C(n+1,n-1)B_{n-1})=-\frac{1}{n+1}(C(n+1,0)B_0+C(n+1,1)B_1+\ldots+C(n+1,n-1)B_{n-1}) 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 = 1 n i k = 1 k + 1 ∑ j = 0 k C ( k + 1 , j ) B j n k + 1 − j \sum_{i=1}^ni^k=\frac{1}{k+1}\sum_{j=0}^kC(k+1,j)B_jn^{k+1-j} ∑i=1nik=k+11∑j=0kC(k+1,j)Bjnk+1−j
struct Bonuli:Factorial
{
vector b;
Bonuli(int N,ll M):Factorial(N,M),b(N,0)
{
for(int i=b[0]=1; i
h 1 = 1 , h n = 4 n − 2 n + 1 h n − 1 = C ( 2 n , n ) n + 1 = C ( 2 n , n ) − C ( 2 n , n − 1 ) h_1 = 1,h_n =\frac{4n−2}{n+1}h_{n−1} =\frac{C(2n,n)}{ n+1 }= C(2n,n)−C(2n,n−1) h1=1,hn=n+14n−2hn−1=n+1C(2n,n)=C(2n,n)−C(2n,n−1)。
在一个格点阵列中,从 ( 0 , 0 ) (0,0) (0,0)点走到 ( n , m ) (n,m) (n,m)点且不经过对角线 x = y x=y 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\ge y$。
把n个带标号的物品划分为若干不相交集合的方案数称为贝尔数,其递推公式: B n = ∑ i = 0 N − 1 C n − 1 i B i B_n=\sum_{i=0}^{N-1}C_{n-1}^iB_i Bn=∑i=0N−1Cn−1iBi
前几项贝尔数: 1 , 2 , 5 , 15 , 52 , 203 , 877 , 4140 , 21147 , 115975 , 678570 , 4213597 , 27644437 , 190899322 , 1382958545 , … 1,2,5,15,52,203,877,4140,21147,115975,678570,4213597,27644437,190899322,1382958545,\ldots 1,2,5,15,52,203,877,4140,21147,115975,678570,4213597,27644437,190899322,1382958545,…
下为 O ( P 2 log P ) O(P^2\log P) O(P2logP)求 B n B_n Bn对P取模。
struct Bell {
static const int P=999999598,N=7284;
int a[4],f[N],s[2][N],i,j,x;
Bell() {
a[0]=2,a[1]=13,a[2]=5281,a[3]=7283;//P的质因数分解
f[0]=f[1]=s[0][0]=1,s[0][1]=2;
for(i=2,x=1; i
考虑容斥,Bell§枚举所有等价情况。对于一种情况,强制了一个等价类里面的数都要相同,其它的可以相同也可以不同。
容斥系数为: ( − 1 ) p − 等 价 类 个 数 ( 每 个 等 价 类 大 小 − 1 ) ! 之 积 (−1)^{p−等价类个数}(每个等价类大小−1)!之积 (−1)p−等价类个数(每个等价类大小−1)!之积。
格雷序列第i个是i^(i>>1)
。长为n的01序列共 2 n 2^n 2n个,下标从 0 … 2 n − 1 0\ldots 2^n-1 0…2n−1。
对于n个点,m个连通块的图,假设每个连通块有a[i]个点,那么用s−1条边把它连通的方案数为 n s − 2 a [ 1 ] a [ 2 ] . . . a [ m ] n^{s−2}a[1]a[2]...a[m] ns−2a[1]a[2]...a[m]。
n维超立方体有 2 n − i C ( n , i ) 2^{n−i}C(n,i) 2n−iC(n,i) 个i维元素。
固定k个点作为根的n个点的带标号有根树森林的方案数是 n n − k − 1 k n^{n−k−1}k nn−k−1k。