求組合數以及組合數取模
阿新 • • 發佈:2018-11-10
1、採用C(a, b) = n! / (m! * (n - m)!),適用範圍為n <= 20
typedef long long ll;
const int maxn=20+5;
ll a[maxn];
void init() {
a[0]=1;
for(int i=1; i<maxn)
a[i]=a[i-1]*i;
}
ll get_c(ll n,ll m) {
if(n<m) return 0;
return a[n]/a[m]/a[n-m];
}
2、採用拓展歐幾里得(較快)
const int MOD=1e9+9 LL fac[N]; void init() { LL i; fac[0]=1; for (LL i = 1; i < N; i++) fac[i] = fac[i - 1] * i % MOD; } LL exgcd(LL a, LL b, LL &x, LL &y) { if (!b) {x = 1; y = 0; return a;} LL d = exgcd(b, a % b, y, x); y -= a / b * x; return d; } LL inv(LL a, LL n) { LL x, y; exgcd(a, n, x, y); return (x + n) % n; } LL C(LL n, LL m) { return fac[n] * inv(fac[m] * fac[n - m] % MOD, MOD) % MOD; }
3、費馬小定理加快速冪(g^(MOD-2)=1/g%MOD,將除法問題轉化為乘法)
LL da[MAXN];//G++ long long void init() { int i; da[0]=1; da[1]=1; for(i=2;i<MAXN;i++) da[i]=i*da[i-1]%MOD; } LL quickmod(LL a,LL b) { LL ans=1; while(b) { if(b&1) { ans=(ans*a)%MOD; b--; } b/=2; a=((a%MOD)*(a%MOD))%MOD; } return ans; } LL C(LL a, LL b) { return (da[a]%MOD)*(quickmod(da[b]*da[a-b]%MOD,MOD-2))%MOD; }