一、组合数的定义
二、预处理逆元求组合数
1.核心
int C(int a,int b)//求组合数
{
if(b>a)
return 0;
return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
2.阶乘及逆元
求阶乘:
a!=(a−1)!∗a
fact[a] = fact[a - 1] * a
求阶乘的逆元:由费马小定理,在模 p下
int qmi(int a,int b)//快速幂模版
{
int ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init()//预处理求阶乘及逆元
{
fact[0]=infact[0]=1;
for(int i=1;i<N;i++)
{
fact[i]=fact[i-1]*i%mod;//阶乘
infact[i]=infact[i-1]*qmi(i,mod-2)%mod;//阶乘逆元
}
}
三、代码模版
#include<iostream>
using namespace std;
#define int long long
const int mod = 1e9+7;
const int N = 1e5+7;
int fact[N],infact[N];//阶乘,阶乘逆元
int qmi(int a,int b)//快速幂模版
{
int ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init()//预处理求阶乘及逆元
{
fact[0]=infact[0]=1;
for(int i=1;i<N;i++)
{
fact[i]=fact[i-1]*i%mod;//阶乘
infact[i]=infact[i-1]*qmi(i,mod-2)%mod;//阶乘逆元
}
}
int C(int a,int b)//求组合数
{
if(b>a)
return 0;
return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
signed main()
{
init();
int a,b;
cin>>a>>b;
cout<<C(a,b);
}
四、例题参考
1.牛客周赛 Round 52题解的F题