利用费马小定理+Lucas求的组合数取模,模数必须为素数。
const ll p=1e9+7;
ll quick_mod(ll a, ll b)
{
ll ans=1;
a%=p;
while(b)
{
if(b&1)
{
ans=ans*a%p;
b--;
}
b>>=1;
a=a*a%p;
}
return ans;
}
ll C(ll n, ll m)
{
if(m>n)return 0;
ll ans=1;
for(ll i=1;i<=m;i++)
{
ll a=(n+i-m)%p;
ll b=i%p;
ans=ans*(a*quick_mod(b,p-2)%p)%p;
}
return ans;
}
ll Lucas(ll n, ll m)
{
if(m==0) return 1;
return C(n%p,m%p)*Lucas(n/p,m/p)%p;
}
利用exgcd+Lucas求的组合数求模,适合模数不为素数的情况。
const ll p=1e9+7;
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
ll r=exgcd(b,a%b,x,y),t;
t=x;
x=y;
y=t-(a/b)*y;
return r;
}
ll C(ll n, ll m)
{
if(m>n)return 0;
ll ans=1;
for(ll i=1;i<=m;i++)
{
ll a=(n+i-m)%p;
ll b=i%p,x,y;
exgcd(b,p,x,y);
ans=ans*(a*(x%p+p)%p)%p;
}
return ans;
}
ll Lucas(ll n, ll m)
{
if(m==0) return 1;
return C(n%p,m%p)*Lucas(n/p,m/p)%p;
}