1. 程式人生 > >學習:Lucas定理

學習:Lucas定理

mark 快速冪 org 函數 ali log a* def turn

模板題

Lucas定理

在數論中,Lucas定理用於計算二項式系數\({\tbinom {m}{n}}\)被質數\(p\)除的所得的余數。

描述

\(p\)為素數,\(a,b\in N_+\),且
\[a=a_kp^k+a_{k-1}p^{k-1}+\cdots+a_1p+a_0\]
\[b=b_kp^k+b_{k-1}p^{k-1}+\cdots+b_1p+b_0\]
這裏\(0\leq a_i,b_i\leq p-1\bigwedge a_i,b_i\in Z(i=0,1,2,3,\cdots,k)\)

則有:
\[C^a_b\equiv C^{b_k}_{a_k}\times C^{b_{k-1}}_{a_{k-1}}\times\cdots\times C^{b_0}_{a_0}{\pmod p}\]

等價形式

由於
\[a_kp^k+a_{k-1}p^{k-1}+\cdots+a_1p\equiv 0 \pmod p\]

\[a\equiv a_0 \pmod p\]
又因為\(a_0<p\),故
\[a\mod p=a_0\]
同理
\[b\mod p=b_0\]

\[C^{a_0}_{b_0}=C^{a\mod p}_{b\mod p}\]
又因為\(a_0<p\),故
\[\lfloor{\frac{a}{p}}\rfloor=a_kp^{k-1}+a_{k-2}p^{k-1}+\cdots+a_1\]
同理
\[\lfloor{\frac{b}{p}}\rfloor=b_kp^{k-1}+b_{k-2}p^{k-1}+\cdots+b_1\]



\[C^{\lfloor\frac{a}{p}\rfloor}_{\lfloor\frac{b}{p}\rfloor}=C^{b_k}_{a_k}\times C^{b_{k-1}}_{a_{k-1}}\times\cdots\times C^{b_1}_{a_1}\]

\[C^a_b\equiv C^{b_k}_{a_k}\times C^{b_{k-1}}_{a_{k-1}}\times\cdots\times C^{b_0}_{a_0}\equiv C^{\lfloor\frac{a}{p}\rfloor}_{\lfloor\frac{b}{p}\rfloor}\times C^{a\mod p}_{b\mod p} {\pmod p}\]

我們真正要用的,就是
\[C^a_b\equiv C^{\lfloor\frac{a}{p}\rfloor}_{\lfloor\frac{b}{p}\rfloor}\times C^{a\mod p}_{b\mod p}{\pmod p}\]

證明

對於素數\(n\)\(m\),滿足\(1\le m\le n-1\), 二項式系數\(C^m_n=\frac{n!}{(n-m)!\cdot m!}=\frac{n(n-1)\cdots(n-m+1)}{m(m-1)\cdots1}\)可被\(n\)整除。由此可得,在母函數中
\[(1+x)^{p}=\sum_{i=0}^{p}(C^{i}_{p}x^{i})\equiv 1+x^{p}{\pmod {p}}\]

對於非負整數\(i\),若\((1+x)^{p^{i}}\equiv 1+x^{p^{i}}{\pmod {p}}\)對於\(i\le t(t\ge 1)\)時成立,則有\[(1+x)^{p^{t+1}}=(1+x)^{p^{t}\times p}=((1+x)^{p^t})^p=1+x^{p\times p^t}=1+x^{p^{t+1}}\]

對於任意非負整數\(i\),都有\((1+X)^{p^{i}}\equiv 1+X^{p^{i}}{\pmod {p}}\)

故對於任意非負整數\(m\)和素數\(p\),將\(m\)\(p\)進制表示,即\[m=\sum _{i=0}^{k}m_{i}p^{i},\]其中\(k\in N_+\)\(m_i\)為整數且\(0\le m_i\le p-1\)。註意到
\[{\begin{aligned}\sum _{n=0}^{m}{C^n_m}x^{n}&=(1+x)^{m}=\prod_{i=0}^{k}\left((1+x)^{p^{i}}\right)^{m_{i}}\\&\equiv \prod_{i=0}^{k}\left(1+x^{p^{i}}\right)^{m_{i}}=\prod _{i=0}^{k}\left(\sum _{n_{i}=0}^{m_{i}}{C_{m_{i}}^{n_{i}}}X^{n_{i}p^{i}}\right)\\&=\prod _{i=0}^{k}\left(\sum _{n_{i}=0}^{p-1}{C_{m_{i}}^{n_{i}}}X^{n_{i}p^{i}}\right)=\sum _{n=0}^{m}\left(\prod _{i=0}^{k}{C_{m_{i}}^{n_{i}}}\right)X^{n}{\pmod {p}},\end{aligned}}\]
其中\(n_i\)\(n\)\(p\)進制表達的第\(i\)位。此即證明了本定理。

所以代碼如下

typedef long long LL;

LL mod;

inline LL pow(LL a,LL b)//快速冪是為了求逆元 
{
    LL ans=1;
    for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;
    return ans;
}

struct Lucas
{
    LL farc[1000005];
    inline void prepare(LL a)
    {
        farc[0]=1;
        for(LL i=1;i<=a;++i)farc[i]=farc[i-1]*i%mod;
    }
    inline LL Csmall(LL m,LL n)//C(m,n)=(n!)/(m!*(n-m)!)
    {
        if(n<m)return 0;
        return farc[n]*pow(farc[m],mod-2)%mod*pow(farc[n-m],mod-2)%mod;//費馬小定理求逆元 
    }
    inline LL C(LL m,LL n)
    {
        if(n<m) return 0;
        if(!n)  return 1;//Lucas的邊界條件 
        return C(m/mod,n/mod)%mod*Csmall(m%mod,n%mod)%mod;//上面證明的Lucas定理 
    }
}Lu;

學習:Lucas定理