卢卡斯定理学习笔记
用于求解 \(\binom{n}{m}\) \(\pmod p\) 其中, \(p\) 为素数且比较小
结论:
所求数同余于它在 \(p\) 进制分解下组合数的乘积
对于质数 \(p\), 所有 \(j\in [1,p)\) 均有
\(\tbinom{p}{j}=\frac{p!}{j!(p-j)!}=\frac{(p-1)!}{(j-1)!(p-j)!} * \frac{p}{j}=\tbinom{p-1}{j-1}*\frac{p}{j}\equiv0 \pmod p\)
\(\therefore (1+j)^p=1+\sum_{i=1}^{p-1}\tbinom{p}{i}*j^i+j^p\equiv 1+j^p\pmod p\)
令 $ n=sp+q , m=lp+r $ (\(0\leq p,r<q\))
则 \((1+x)^{sp+q} \equiv (1+x)^{sp}(1+x)^q \equiv (1+x^p)^s(1+x)^q \equiv(\sum_{i=0}^{s} \tbinom{s}{i} * x^{ip}) * (\sum_{j=0}^{q} \tbinom{q}{j} * x^j)\pmod p\)
观察 \(\large x^m\)项
\(\tbinom{n}{m} * x^m \equiv \tbinom{s}{l} * x^{lp} * \tbinom{q}{r} * x^r \pmod p\)
\(\tbinom{n}{m} * x^m \equiv (\tbinom{s}{l} * \tbinom{q}{r}) * x^m \pmod p\)
又因为 $ p$为素数,所以两边同时约去 \(\large x^m\)
则 \(\tbinom{n}{m} \equiv \tbinom{s}{l} * \tbinom{q}{r} \equiv \tbinom{n/p}{m/p} * \tbinom{n \bmod p}{m \bmod p}\pmod p\)
即 $ C_{n}^m \equiv C_{n/p}^{m/p} * C_{n \bmod p}^{m \bmod p} \pmod p$
证毕!
Code:
#include<stdio.h>
#define ll long long
ll p;
inline ll qpow(ll a,ll b){
if(b==1) return a;
ll t=qpow(a,b/2);
t=t*t%p;
if(b&1) t=t*a%p;
return t;
}
inline ll C(ll n,ll m){
if(n<m) return 0;
if(m>n-m) m=n-m;
ll a=1,b=1;
for(int i=0;i<m;i++){
a=(a*(n-i))%p;
b=(b*(i+1))%p;
}
return a*qpow(b,p-2)%p;
}
inline ll Lucas(ll n,ll m){
if(m==0) return 1;
return Lucas(n/p,m/p)*C(n%p,m%p)%p;
}
ll n,m;
int T;
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld%lld%lld",&n,&m,&p);
printf("%lld\n",(Lucas(n+m,m))%p);
}
}