卢卡斯定理证明
一、问题引入
\(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)
\]