一个组合数的简单模板

用到了阶乘和阶乘逆元预处理(线性求逆元)

/*
组合数 C(n, m) 模板
lzh007  2020/6/1

****使用注意N的范围设定和模mod的范围设定***

*/

#include<iostream>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int NN = 1e5 + 17;//范围大小
const LL mod = 1e9 + 7;//模大小
LL f[NN], inv[NN], finv[NN];
//f存储阶乘,inv辅助求阶乘逆元,finv存阶乘逆元,所有值均已对模取余

//取模快速幂
LL km(LL base, LL b) {
	LL ans = 1;
	while (b > 0) {
		if (b & 1)
			ans = (ans * base) % mod;
		base = (base * base) % mod;
		b /= 2;
	}
	return ans;
}

//初始化f[NN], inv[NN], finv[NN]
void init() {
	f[0] = inv[0] = finv[0] = 1;
	f[1] = inv[1] = finv[1] = 1;
	for (LL i = 2; i < NN; i++) {
		f[i] = f[i - 1] * i % mod;
		inv[i] = (mod - mod / i) * inv[mod % i] % mod;
		finv[i] = (finv[i - 1] * inv[i]) % mod;
	}
}

//经过预处理后求C(n, m)
LL cnm(LL n, LL m) {
	return ((f[n] * finv[m] % mod) * finv[n - m]) % mod;
}

int main() {
	init();
	LL n, m;
	while (cin >> n >> m) {
		cout << "C(" << n << ', ' << m << ") 对 " << mod << " 取模的大小是 " << cnm(n, m) << endl;
	}
	return 0;
}

ps:小白一个,请多多指教

猜你喜欢

转载自blog.csdn.net/qq_44724908/article/details/106493809