求组合数
ll C(ll n,ll m) {ll ret=1;for(ll i=1; i<=m; ++i)ret=ret*(n-i+1)/i; return ret;}
组合数打表
#include <bits/stdc++.h>
using namespace std;
int C[1005][1005];
int main()
{
C[0][0] = 1;
for (int i = 1; i <= 1000; i++)
{
C[i][0] = 1;
for (int j = 1; j <= 1000; j++)
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
cout << C[4][3] << endl;
return 0;
}
快速幂求组合数
typedef long long int ll;
const int mod=1e9+7;
ll qpow(ll a,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
ll jc(ll n){
ll ans=1;
for(ll i=1;i<=n;i++)ans=ans*i%mod;
return ans;
}
ll C(ll n,ll m){
ll ans=1;
ans=ans*jc(n)%mod;
ans=ans*qpow(jc(m),mod-2)%mod;
ans=ans*qpow(jc(n-m),mod-2)%mod;
return ans;
}
线性打表
const ll maxn=1e5+50;
ll a[maxn],b[maxn];//a[i]是i的阶乘,b[i]是阶乘的除法逆元,两者用于求组合数
ll qpow(ll n,ll k,ll mod){
ll res=1;
n=n%mod;
while(k){
if(k&1)res=res*n%mod;
n=n*n%mod;
k>>=1;
}
return res;
}
void init(){
a[0]=b[0]=1;
for(int i=1;i<maxn;++i){
a[i]=(a[i-1]*i)%mod;
}
b[maxn-1]=qpow(a[maxn-1],mod-2,mod); //maxn-1必须小于mod
for(int i=maxn-1;i>0;i--)
b[i-1]=b[i]*i%mod;
}
ll C(ll n,ll m){
if(n<m)return 0;
return a[n]*b[m]%mod*b[n-m]%mod;
}
//Lucas(n,m) //C(N,M)
ll Lucas(ll n, ll m){ //卢卡斯定理,求大组合数,且mod必须是质数,否则需要先对mod拆分然后用中国剩余定理取合并
if(m ==0) return 1;
else return (C(n%mod, m%mod)*Lucas(n/mod, m/mod))%mod;
}