博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lucas 定理
阅读量:5951 次
发布时间:2019-06-19

本文共 2116 字,大约阅读时间需要 7 分钟。

Lucas 定理:n、m是非负整数,p是素数。那么:

1、C(n,m)% p = Lucas(n,m,p)

2、Lucas(n,m,p)= (C(n%p,m%p)% p)*Lucas(n/p,m/p,p)

证明:

我们将n和m表示成p进制数:n = akak-1..a1(p)  m = bkbk-1...b1(p)(位数不够高位补0)

通过简单分析,可以得到: C(n,m)和C(a1,b1)*C(a2,b2)*...*C(ak,bk)关于p同余

n = ak*p^(k-1) + ... + a1      m = bk*p^(k-1) + ... + b1

关于为什么同余,可以通过上面的式子观察出来,也可通过精确推导得出,篇幅所限,这里也不在累述。

 

我们已经知道了,Lucas定理的公式,但是关键是怎么编码来得出结果呢?

也许你会说,那还不简单,直接递归就搞定了,其实没那么简单,还有一个重要的问题没解决,C(ai,bi)(mod p)的求法。

这里还涉及到逆元以及欧拉-费马定理的应用。

 

关于C(n,m)(mod p)(p为素数)的求法:

1、C(n,m)= n! / (m! * (n - m)!) (组合数的求法)

2、(a / b) (mod p) = (a * x) (mod p) x表示b的逆元 并且 b * x = 1 (mod p)(乘法逆元)

3、b^phi(p) = 1 (mod p)(b和p互质,phi(p)为p的欧拉函数值) (欧拉-费马定理)

通过上述三式,我们知道了C(n,m)(mod p)的求法,用fac[i] = i! % p

C(n,m)(mod p) = fac[n] * pow(fac[m]*fac[n-m],p-2)

code:

1 #include 
2 typedef __int64 LL; 3 const int MAXN = 1000005; 4 LL n, m, p; 5 LL fac[MAXN]; 6 7 // 得到阶乘 fac[i] = i! % p 8 void GetFact() 9 {10 fac[0] = 1;11 for (LL i = 1; i < MAXN; ++i)12 fac[i] = fac[i - 1] * i % p;13 }14 15 // 快速模幂 a^b % p16 LL Pow(LL a, LL b)17 {18 LL temp = a % p;19 LL ret = 1;20 while (b)21 {22 if (b & 1) ret = ret * temp % p;23 temp = temp * temp % p;24 b >>= 1;25 }26 return ret;27 }28 29 /*30 欧拉定理求逆元31 32 (a / b) (mod p) = (a * x) (mod p) x表示b的逆元 并且 b * x = 1 (mod p) 只有b和p互质才存在逆元33 34 b * x = 1 (mod p) x是b关于p的逆元35 36 b^phi(p) = 1 (mod p)37 38 b * b^(phi(p) - 1) (mod p) = b * x (mod p)39 40 x = b^(phi(p) - 1) = b^(p - 2)41 42 (a / b) (mod p) = (a * x) (mod p) = (a * b^(p - 2)) (mod p)43 44 经过上面的推导,得出:45 46 (a / b) (mod p) = (a * b^(p - 2)) (mod p) (b 和 p互质)47 48 */49 LL Cal(LL n, LL m)50 {51 if (m > n) return 0;52 return fac[n] * Pow(fac[m] * fac[n - m], p - 2) % p;53 }54 55 LL Lucas(LL n, LL m)56 {57 if (m == 0) return 1;58 return Cal(n % p, m % p) * Lucas(n / p, m / p) % p;59 }60 61 int main()62 {63 int nCase;64 scanf("%d", &nCase);65 while (nCase--)66 {67 scanf("%I64d %I64d %I64d", &n, &m, &p);68 printf("%I64d\n", Lucas(n, m));69 }70 return 0;71 }

 

转载于:https://www.cnblogs.com/ykzou/p/4494902.html

你可能感兴趣的文章
《Adobe Photoshop CS4中文版经典教程》—第1课1.7节检查更新
查看>>
《Arduino开发实战指南:机器人卷》一3.6 编程原理与示例程序
查看>>
KVM基础安装,手动创建桥
查看>>
《CCNP TSHOOT 300-135学习指南》——1.2节结构化故障检测与排除方法
查看>>
《ANTLR 4权威指南》——第2章纵观全局
查看>>
Babel 6.25 版本发布,JavaScript 编译器
查看>>
2017 年全球十大突破技术:逼格很高很难懂
查看>>
《机器人爱好者(第2辑)》——部署机械手或末端执行器
查看>>
《R语言与数据挖掘最佳实践和经典案例》—— 3.5 将图表保存到文件中
查看>>
《Hack与HHVM权威指南》——1.1 为什么使用类型检查器
查看>>
《C#初学者指南》一第1章 初识C#
查看>>
《信息存储与管理(第二版):数字信息的存储、管理和保护》—— 2.1 应用...
查看>>
《机器学习与数据科学(基于R的统计学习方法)》——2.8 读取JSON文件
查看>>
《iOS9开发快速入门》——第1章,第1.4节小结
查看>>
MariaDB 源码调试
查看>>
理解Java机制最受欢迎的8幅图
查看>>
WannaCry感染文件恢复方法,企业再也不用愁了!
查看>>
【javascript】 的严格模式 详解
查看>>
八大排序算法的 Python 实现
查看>>
三个快速便捷的命令行小贴士
查看>>