卢卡斯定理的模板题
利用隔板法易知组合数C(n+m,m)
ans=C(n+m,m)%p
快速幂求逆元
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
typedef long long ll;
const int maxn= 100000;
ll mod;//=1e4+7;
ll f[maxn];
void init()
{
f[0]=1;
for(ll i=1; i<=mod; i++)
f[i]=(i*f[i-1])%mod;
}
long long pow1(long long n,long long m )
{
long long ans = 1;
while(m > 0)
{
if(m & 1)ans = (ans * n) % mod;
m = m >> 1;
n = (n * n) % mod;
}
return ans;
}
long long lucas(ll n,ll m)
{
ll ans=1;
while(n&&m)
{
ll x,y;
x=n%mod;
y=m%mod;
if(x<y)
return 0;
// printf("%lld %lld %lld\n",f[x],f[y],f[x-y]);
ans=ans*f[x]*pow1(f[y]*f[x-y]%mod,mod-2)%mod;
n/=mod;
m/=mod;
}
return ans%mod;
}
int main()
{
ll n,m;
int t;
cin>>t;
while(t--)
{
scanf("%lld%lld%lld",&n,&m,&mod);
init();
printf("%lld\n",lucas(n+m,m));
}
return 0;
}