组合数-CSDN博客

47 阅读1分钟

当组合数很大时,要用唯一分解定理。

const int N = 10000;
bool vis[N + 1];
int p[1229], cnt_p;
int getPrime(int n) {
	memset(vis, 1, sizeof vis);
	int cnt = 0;
	for (int i = 2; i <= n; ++i) {
		if(vis[i]) {
			p[cnt++] = i;
		}
		for (int j = 0; j < cnt && (i *p[j] <= n); ++j) {
			vis[i * p[j]] = 0;
			if(i % p[j] == 0) break;
		}
	} 
	return cnt;
}
int e[1229];
inline void add_integer(int n, int d) {
	//d = 1,表示乘;-1表示除
	for(int i = 0; i < cnt_p; ++i) {
		while(n % p[i] == 0) {
			n /= p[i];
			e[i] += d;
		} 
		if(n == 1) break;
	} 
} 
inline void add_factorial(int n, int d) {
	for (int i = 1; i <= n; ++i) 
		add_integer(i, d);
}


C(n, m) = C(n + 1, m) - C(n + 1, m - 1).

C(n, m) = C(n, m - 1) * (n - m +1) / m.

\

记录一下这个函数,n个物品中选m个的选法的函数。

参数n, m。返回值:选法种数,n,和m不是很大。

long long f(int n,int m){
	if(m==0 || m > n) return 1;
	return f(n,m-1) * (n-m+1) / m;
}



超级大的话就用《算法竞赛入门经典》中的分解法