L
u
c
a
s
Lucas
Lucas 定理:对于质数
p
p
p,有
(
n
m
)
m
o
d
p
=
(
⌊
n
/
p
⌋
⌊
m
/
p
⌋
)
⋅
(
n
m
o
d
p
m
m
o
d
p
)
m
o
d
p
\binom{n}{m}\bmod p = \binom{\left\lfloor n/p \right\rfloor}{\left\lfloor m/p\right\rfloor}\cdot\binom{n\bmod p}{m\bmod p}\bmod p
(mn)modp=(⌊m/p⌋⌊n/p⌋)⋅(mmodpnmodp)modp
等价于
C
(
n
,
m
)
%
p
=
C
(
n
/
p
,
m
/
p
)
∗
C
(
n
%
p
,
m
%
p
)
%
p
C(n,m)\%p=C(n/p,m/p)*C(n\%p,m\%p)\%p
C(n,m)%p=C(n/p,m/p)∗C(n%p,m%p)%p
边界条件:当
m
=
0
m=0
m=0 的时候,返回
1
1
1 。
C o d e : Code: Code:
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long ll;
using namespace std;
ll qpow(ll a,ll b,ll p){//快速幂
ll ans=1,base=a;
while(b){
if(b&1) ans*=base,ans%=p;
base*=base,base%=p;
b>>=1;
}
return ans;
}
ll C(ll n,ll m,ll p){//组合数
if(n<m) return 0;
if(m>n-m) m=n-m;
ll a=1,b=1;
FOR(i,0,m-1){
a=(a*(n-i))%p;
b=(b*(i+1))%p;
}
return a*qpow(b,p-2,p)%p;//费马小定理
}
ll Lucas(ll n,ll m,ll p){//卢卡斯定理
if(m==0) return 1;
return Lucas(n/p,m/p,p)*C(n%p,m%p,p)%p;
}
int main(){
int T;cin>>T;
while(T--){
ll n,m,p;
cin>>n>>m>>p;
cout<<Lucas(n+m,m,p)%p<<endl;
}
return 0;
}