lucas定理,乘法逆元。
1.卢卡斯原理。
求(a/b)%c,但a又特别大,就要求乘法逆元k,使(a*k)%c与(a/b)%c等价。满足a*k≡1(modc)的k值就是a关于c的乘法逆元。
证明略过,可以用欧几里得扩展算法或欧拉定理求得。
欧拉定理表明,若为正整数,且
互素,
,则
。其中
为欧拉函数,
为同余关系。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<ctype.h>
#include<algorithm>
#include<string>
#define PI acos(-1.0)
#define maxn 100005
#define INF 1<<25
typedef long long ll;
using namespace std;
ll num[maxn];
ll qpow(ll aa,ll bb,ll cc)
{
ll ans=1,rec=aa;
while(bb)
{
if(bb&1)
ans=ans*rec%cc;
rec=rec*rec%cc;
bb>>=1;
}
return ans;
}
ll lucas(ll aa,ll bb,ll cc)
{
ll ans=1;
while(aa&&bb)
{
ll a=aa%cc,b=bb%cc;
if(b>a)
return 0;
ans=ans*num[a]*qpow(num[b]*num[a-b]%cc,cc-2,cc)%cc;
aa/=cc;
bb/=cc;
}
return ans;
}
int main()
{
int tot;
ll n,m,lim;
scanf("%d",&tot);
while(tot--)
{
cin>>n>>m>>lim;
num[0]=1;
for(int i=1; i<=lim; i++)
{
num[i]=num[i-1]*i%lim;
}
cout<<lucas(m+n,n,lim)<<endl;
}
}