Lucas定理
C(m+n,m)%p
好看点的模板
1.(常用、标准)
/*
Lucas定理
C(m+n,m)%p
Exe.Time 733MS
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll pow_mod(ll a,ll b,ll mod)
{
ll ans = 1;
a %= mod;
while(b)
{
if(b&1)
ans = ans * a % mod;
b >>= 1;
a = a*a%mod;
}
return ans;
}
ll GetC(ll n,ll m,ll mod)
{
if(m > n)
return 0;
if(m > n - m)
m = n - m;
ll a = 1,b = 1;
while(m)
{
a = a*n%mod;
b = b*m%mod;
m--;
n--;
}
return a * pow_mod(b,mod-2,mod)%mod;
}
ll Lucas(ll n,ll k,ll mod)
{
if(k == 0)
return 1;
return GetC(n%mod,k%mod,mod)*Lucas(n/mod,k/mod,mod)%mod;
}
int main()
{
int t;
ll n,m,q;
cin >> t;
while(t--)
{
scanf("%lld%lld%lld",&n,&m,&q);
printf("%lld\n",Lucas(n+m,m,q));
}
return 0;
}
2.
/*
Lucas定理
C(m+n,m)%p
Exe.Time 1216MS
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1000005;
typedef long long LL;
LL n,m,p;
LL f[N];
LL gcd(LL a,LL b) {return b ? gcd(b,a%b) : a;}
LL lcm(LL a,LL b) {return a / gcd(a,b) * b;}
void Init(LL p)
{
f[0] = 1;
for(int i = 1;i <= p;i++)
f[i] = (f[i-1]*i) % p;
}
LL pow_mod(LL a,LL b,LL MOD)
{
LL ans = 1;
while(b)
{
if(b%2)
ans = ans*a%MOD;
a = a*a%MOD;
b /= 2;
}
return ans;
}
LL Lucas(LL n,LL m,LL p)
{
LL ans = 1;
while(n && m)
{
LL a = n%p,b = m%p;
if(a < b)
return 0;
ans = (ans*f[a]*pow_mod(f[b]*f[a-b]%p,p-2,p))%p;
n /= p;m /= p;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d%I64d",&n,&m,&p);
Init(p);
LL ans = Lucas(n+m,m,p);
printf("%I64d\n",ans);
}
return 0;
}