Just Wait...

目前组合数学我学过的

const int Mod = 1e9 + 7;

int n, m, d[1000010], fac[1000010], ifac[1000010], h[1000010], stl[1010][1010], stl1[50010][205];

int qp(int x, int y){ // 快速幂
	x %= Mod;
	int res = 1;
	while(y){
		if(y & 1) (res *= x) %= Mod;
		(x *= x) %= Mod;
		y >>= 1;
	}
	return res;
}

void init(){ // 阶乘、逆元预处理
	ifac[0] = fac[0] = 1;
	for(int i = 1; i <= 1000; i ++) fac[i] = fac[i - 1] * i % Mod;
	for(int i = 1; i <= 1000; i ++) ifac[i] = qp(fac[i], Mod - 2);
}

void inith(){ // 卡特兰数
	h[0] = 1;
	for(int i = 1; i <= 1000000; i ++) h[i] = h[i - 1] * (4 * i - 2) % Mod * qp(i + 1, Mod - 2) % Mod;
}

int C(int x, int y){ // 组合数
	return fac[x] % Mod * ifac[y] % Mod * ifac[x - y] % Mod;
}

void init2(){ // 错排
	d[0] = 1, d[1] = 0, d[2] = 1;
	for(int i = 3; i <= 1000000; i ++) d[i] = (i - 1) * (d[i - 1] + d[i - 2]) % Mod;
}

int calt(int x, bool k){ // 卡特兰; 1:预处理;2:现场处理
	if(k) return h[x];
	return (C(2 * x, x) - C(2 * x, x - 1) % Mod + Mod) % Mod;
}

void initstl(){ // 第二类斯特林数
	stl[0][0] = 1;
	for(int i = 1; i <= 1000; i ++){
		for(int j = 1; j <= i; j ++){
			stl[i][j] = (stl[i - 1][j - 1] + j * stl[i - 1][j] % Mod) % Mod;
		}
	}
}

void initstl1(){// 第一类斯特林数
	stl1[0][0] = 1;
	for(int i = 1; i <= 50000; i ++){
		for(int j = 1; j <= min(i, 200ll); j ++){
			stl1[i][j] = (stl1[i - 1][j - 1] + (i - 1) * stl1[i - 1][j] % Mod) % Mod;
		}
	}
}
posted @ 2025-08-12 18:33  Hty111  阅读(5)  评论(0)    收藏  举报