时间复杂度$O(m)$,当计算$\binom{30}{15}=155117520$ 时,正溢出了long long型,所以答案计算不正确
using ll = long long;
ll comb(ll n, ll m) {
ll a = 1, b = 1;
for (ll i=n,j=1; i>n-m; i--,j++) {
a *= i;
b *= j;
}
return a/b;
}
时间复杂度$O(m)$,能够计算更大的组合数
// comb(n, m) = (n-m+1)/m * comb(n, m-1)
// comb(n, m-1)是整数,(n-m+1)*comb(n, m-1)是整数,(n-m+1)*comb(n, m-1)/m是整数
// comb(n, m-1) = (n-m+2)/(m-1) * comb(n, m-2)
ll comb(ll n, ll m) { // m <= n;
if (m == 0) return 1;
return comb(n, m-1)*(n-m+1)/m;
}
ll comb(ll n, ll m) {
ll rt = 1;
for (ll i=n,j=1; i>n-m; i--,j++) {
rt = rt*i/j;
}
return rt;
}
时间复杂度$O(n)$
using ll = long long;
const ll MOD = 1e9+7;
// O(n)
ll C(ll n, ll m) { //n个里选m个
ll inv[n+1];
inv[1] = 1;
for (int i=2; i<=n; i++) {
inv[i] = (MOD-MOD/i)*inv[MOD%i]%MOD;
}
ll rt = 1;
for (int i=m; i>0; i--) {
rt = rt*(n-i+1)%MOD*inv[i]%MOD;
}
return rt;
}
$n! \equiv (n+1)!^{-1}*(n+1) \pmod p$
预处理$O(n)$打表
using ll = long long;
const ll MOD = 1e9+7;
#define N 100005
ll fac[N], inv_fac[N];
ll fpow(ll x, ll p, ll m) {
ll rt = 1;
while (p) {
if (p&1) rt *= x, rt %= m;
x *= x; x %= m;
p >>= 1;
}
return rt;
}
void pre() {
fac[0] = 1;
for (int i=1; i<N; i++) {
fac[i] = fac[i-1]*i%MOD;
}
inv_fac[N-1] = fpow(fac[N-1], MOD-2, MOD);
for (int i=N-2; i>=0; i--) {
inv_fac[i] = inv_fac[i+1]*(i+1)%MOD;
}
}
// O(1)
int comb(int n, int m) {
return fac[n]*inv_fac[m]%MOD*inv_fac[n-m]%MOD;
}
求大组合数$\binom{n}{m}$,若m较小,n巨大,则可以$O(n)$求出。
using ll = long long;
ll fpow(ll x, ll p, ll MOD) {
ll rt = 1;
while (p) {
if (p&1) rt *= x, rt %= MOD;
x *= x;
x %= MOD;
p >>= 1;
}
return rt;
}
// n!/(m!(n-m)!)
ll comb(ll n, ll m, ll MOD) {
ll u = 1, d = 1;
for (ll i = n; i>n-m; i--) {
u = u*i%MOD;
d = d*(i-n+m)%MOD;
}
return u*fpow(d, MOD-2, MOD)%MOD;
}
模较小质数p=O(1e5),用卢卡斯定理