卢卡斯定理证明

卢卡斯定理

一、问题引入

\(Q\)次询问,每次询问组合数\(C(n,m)\% p\)
Problem 1:

  • \(n\le 10^5, m\le 10^5, p\le 2\times 10^9, Q\le 10^5, p\ is\ prime\)

预处理出\([0,10^5)\)阶乘和\([0,10^5)\)阶乘的逆元
然后每次可以\(O(1)\)查询

Problem 2:

  • \(n\le 10^9, m\le 10^9, p\le 10^6, Q\le 10^5 p\ is\ prime\)

这时候就不能去预处理\(10^9\)的数量级的阶乘了,但是发现模数比较小,就要从模数下手,那么起始就是要用卢卡斯定理了

二、卢卡斯定理

首先先给出结论:

\[C(n,m)≡C(n\%p,m\%p)\times C(n/p,m/p)\ (mod\ p) \]

例题和代码:
🔗

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
typedef long long int LL;
const int MAXN = 1e5+7;
LL inv[MAXN], n, m, p, f[MAXN], rf[MAXN];
LL C(int n, int m){ return f[n] * rf[m] % p * rf[n-m] % p; }
LL Lucas(int n, int m){
    LL ret = 1;
    while(n and m){
        int nn = n % p, mm = m % p;
        if(nn<mm) return 0;
        ret = ret * C(nn,mm) % p;
        n /= p; m /= p;
    }
    return ret;
}
void solve(){
    cin >> m >> n >> p;
    n += m;
    inv[1] = 1; f[0] = 1; rf[0] = 1; 
    for(int i = 2; i < p; i++) inv[i] = (p-p/i) * inv[p%i] % p;
    for(int i = 1; i < p; i++) f[i] = f[i-1] * i % p;
    for(int i = 1; i < p; i++) rf[i] = rf[i-1] * inv[i] % p;
    cout << Lucas(n,m) << endl;
}
int main(){
    int tt; ____();
    for(cin >> tt; tt; tt--) solve();    
    return 0;
}

如果不想看证明的话现在就可以结束了

三、证明

引理一

\[C(p,x) ≡ 0\ (mod\ p), 0<x<p \]

证明:

\[C(p,x)≡\frac{p!}{x!\cdot (p-x)!}≡\frac{p\cdot (p-1)!}{x\cdot(x-1)!\cdot(p-x)!}≡p\cdot inv(x)\cdot C(p-1,x-1)≡0\ (mod\ p) \]

引理二

\[(1+x)^p≡1+x^p\ (mod\ p) \]

证明:
先进行二项式展开

\[(1+x)^p=\sum_{i=0}^{p}C(p,i)x^i \]

根据引理一

\[\sum_{i=0}^{p}C(p,i)x^i ≡ C(p,0)x^0 + C(p,p)x^p ≡ 1 + x^p\ (mod\ p) \]

接下来推导卢卡斯定理:

\[假设 n=q_np+r_n, m = q_mp+r_m \]

\[(1+x)^{n} ≡ (1+x)^{q_np+r_n} ≡ (1+x)^{q_np}\cdot (1+x)^{r_n}≡[(1+x)^p]^{q_n}\cdot (1+x)^{r_n} \]

\[≡(1+x^p)^{q_n}\cdot (1+x)^{r_n}≡\sum_{i=0}^{q_n}C(q_n,i)x^{p\cdot i}\cdot \sum_{j=0}^{r_n}C(r_n,j)x_j\ (mod\ p) \]

\[(1+x)^n = \sum_{i=0}^{n}C(n,i)x^i \]

得到

\[\sum_{i=0}^{n}C(n,i)x^i≡\sum_{i=0}^{q_n}C(q_n,i)x^{p\cdot i}\cdot \sum_{j=0}^{r_n}C(r_n,j)x_j\ (mod\ p) \]

取两边\(x^m\)次项的系数,因为\(m=q_mp+r_m\),所以对于等式右边最多只有一种情况满足

\[C(n,m) ≡ C(q_n,q_m)\cdot C(r_n,r_m) ≡ C(n/p,m/p)\cdot C(n\%p,m\%p)\ (mod\ p) \]

posted @ 2020-07-03 14:21  _kiko  阅读(433)  评论(0编辑  收藏  举报