Lucas 定理简单证明
前言
Oi wiki 和网上博客的证明都没完全看懂,最后还是自己推出来的。。这里记录一下思路。
Lucas 定理
对于质数
可以接着递归展开
朴素的Lucas 定理可以加速大组合数对质数取模的运算。
证明Lucas 定理
二项式定理
对于
引理 1
证明引理 1:
引理 2
证明引理 2:
先二项式定理展开有
由引理 1,上式只有
证明Lucas 定理
不妨把
由
由引理 2,
再二项式定理展开,有
那么
不难验证
考虑其它解形如
也就得到
得证。
模板代码
Luogu P3807 【模板】卢卡斯定理/Lucas 定理 Link
就是Lucas 定理的模板。但是数据范围太水了,预处理下来甚至不需要Lucas 定理就能过。
AC代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e5 + 10; int T, n, m, p; ll frac[maxn]; int qpow(ll x, int y) { ll res = 1; while(y) { if(y & 1) (res *= x) %= p, y--; (x *= x) %= p; y /= 2; } return (int)res; } int C(int n, int m){ return (m > n) ? 0 : frac[n] * qpow(frac[m], p - 2) % p * qpow(frac[n - m], p - 2) % p; } int lucas(int n, int m) { return (m == 0) ? 1 : C(n % p, m % p) * lucas(n / p, m / p) % p; } void init() { frac[0] = 1ll, frac[1] = 1ll; for(int i = 2; i <= 100000; i++) frac[i] = 1ll*frac[i - 1] * i % p; return; } int main() { ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> T; while(T--) { cin >> n >> m >> p; init(); cout << lucas(n + m, n) << endl; } return 0; }
本文作者:Ydoc770
本文链接:https://www.cnblogs.com/Ydoc770/p/18689220
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步