卢卡斯定理
卢卡斯定理(Lucas Law)
核心内容
对正整数 , , 质数 , 有
证明
从 开始证明
由于是模 意义下的运算, 且 , 所以对 有
代入到二项式定理可得
将二项式指数推广到正整数 , 设 ,
使用前面的结论 , 整理上式得
代入二项式定理
整理得
由于 , 所以任意一组 , 对应唯一的 值, 和 内的每一个数一一对应, 所以将式子改写为枚举 的值.
所以, 模 意义下, 的 次项系数 就是
定理得证
模板Luogu3807
求 组
, 为质数
由于 为质数且 , 可以用 Lucas 定理
递归求解
unsigned Lucas (unsigned x, unsigned y) {
if(x <= Mod && y <= Mod) {
return Binom(x, y);
}
return ((long long)Binom(x % Mod, y % Mod) * Lucas(x / Mod, y / Mod)) % Mod;
}
递归边界就是 , 直接 求出
需要注意的是, 当遇到取模之后 时, , 因为 不存在 次项 (括号内的 是自变量, 指数 是函数调用的参数)
还有, 当 的时候, , 尽管不加这个特判返回值也是 , 但是不知道为什么我还是加了
unsigned Binom (unsigned x, unsigned y) {
unsigned Up(1), Down(1);
if (y > x) {
return 0;
}
if(!y) {
return 1;
}
for (register unsigned i(2); i <= x; ++i) {
Up = ((long long)Up * i) % Mod;
}
for (register unsigned i(2); i <= y; ++i) {
Down = ((long long)Down * i) % Mod;
}
for (register unsigned i(2); i <= x - y; ++i) {
Down = ((long long)Down * i) % Mod;
}
Down = Power(Down, Mod - 2);
return ((long long)Up * Down) % Mod;
}
函数 Binom()
中的 Power()
用来根据欧拉定理求乘法逆元, 即
unsigned Power (unsigned x, unsigned y) {
if(!y) {
return 1;
}
unsigned tmp(Power(((long long)x * x) % Mod, y >> 1));
if(y & 1) {
return ((long long)x * tmp) % Mod;
}
return tmp;
}
最后放出 main()
, 可以看出又多了一句无关紧要的特判, 一看就是让 julian
毒害过的可怜人
int main() {
t = RD();
for (register unsigned T(1); T <= t; ++T){
Clr();
if(!(n && m)) {
printf("1\n");
continue;
}
printf("%u\n", Lucas(n + m, n));
}
return Wild_Donkey;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
2020-03-14 数论: 莫比乌斯反演 ( 三 ) 证明