题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3037
Lucas定理
A、B是非负整数,p是质数。A B写成p进制:A=a[n]a[n-1]...a[0],B=b[n]b[n-1]...b[0]。
则组合数C(A,B)与C(a[n],b[n])*C(a[n-1],b[n-1])*...*C(a[0],b[0]) mod p同余
即:Lucas(n,m,p)=C(n%p,m%p)*Lucas(n/p,m/p,p)
AC代码:
#include <iostream>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
typedef long long LL;
const int N=52;
const LL II=29;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
LL p,xh[100100];
void www()
{
xh[0]=1;
for(LL i=1;i<=p;i++)
xh[i]=xh[i-1]*i%p;
}
LL power(LL a,LL b)
{
LL ans=1;
a=a%p;
while(b)
{
if(b&1) ans=(ans*a)%p;
a=(a*a)%p;
b=b/2;
}
return ans;
}
LL love(LL n,LL m)
{
LL ans=1;
while(n&&m)
{
LL nn=n%p,mm=m%p;
if(nn<mm)
return 0;
ans=ans*xh[nn]*power(xh[mm]*xh[nn-mm]%p,p-2)%p;
n/=p;
m/=p;
}
return ans%p;
}
int main()
{
LL n,m;
int T;
cin>>T;
while(T--)
{
scanf("%I64d%I64d%I64d",&n,&m,&p);
www();
printf("%I64d\n",love(n+m,n));
}
return 0;
}
/*
2
1 2 5
2 1 5
6 4 5
*/