卢卡斯定理学习笔记

用于求解 \(\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);
    }
}
posted @ 2019-03-17 11:41  Kreap  阅读(160)  评论(0编辑  收藏  举报