关于C(m,n)%p的故事
序
遥远的\(\mod p\)(\(p\)是质数)大陆有一个恶魔:\[C(m,n)={m!\over n! (m-n)!}\]
于是大家有了各种求逆元的方法。这里MOD = p。
壹
for (int i = 0; i < MOD; i ++)
rev_fact[i] = pow_mod(i, MOD - 2, MOD);
rev_fact[MOD - 1] = pow_mod(MOD - 1, MOD - 2, MOD);
for (int i = MOD - 2; i >= 0; i --)
rev_fact[i] = (i64) rev_fact[i + 1] * (i + 1) % MOD;
下面的方法正确性在这里:
rev_fact[0] = rev_fact[1] = 1;
for (int i = 2; i < MOD; i ++)
rev_fact[i] = (i64) rev_fact[MOD % i] * (MOD - MOD / i) % MOD;
int mod_inverse(int a, int m) {
int x, y;
extgcd(a, m, x, y);
return (m + x % m) % m;
}
rev_fact[0] = 1;
for (int i = 1; i < MOD; i ++) rev_fact[i] = mod_inverse(i, MOD);
当然,最后都要加上:
for (int i = 2; i < MOD; i ++)
rev_fact[i] = (i64) rev_fact[i] * rev_fact[i - 1] % MOD;
通过上面的预处理,有人使用下面的方法来对抗恶魔:
int C(int m, int n) {
return (i64) fact[m] * rev_fact[n] % MOD * rev_fact[m - n] % MOD;
}
这样,\(\mod p\)大陆稳定了一段时间。
贰
随着恶魔力量不断加强,\(m,n\)不断变大,甚至超过了\(p\)。
于是大家尝试通过计算\(n! \mod p\),进而计算\(C(m,n)\)。
有人说,当\(n < p\)时,\(n! \equiv 0 \mod p\)。
又有反对的声音:我们应该把被\(p\)整除的因子提出来。
于是有人提出计算\(n! \mod p\)的方法,来计算\(n!\equiv a p^e\):
int mod_fact(int n, int p, int &e) {
e = 0;
if (n == 0) return 1;
int ret = mod_fact(n / p, p, e);
e += n / p;
// 根据威尔逊定理 (p-1)! = -1
if ((n / p) & 1) return (int) res * (p - fact[n % p]) % p;
return (int) res * fact[n % p] % p;
}
这时,大家告诉有人,他找到了Lucas定理!
于是,恶魔就这样被虐了!
int Lucas(int m, int n) {
if (n > m) return 0;
if (m < 0 || n < 0) return 0;
if (m < MOD && n < MOD)
return (i64) fact[m] * rev_fact[n] % MOD *
rev_fact[m - n] % MOD;
else
return (i64) Lucas(m / MOD, n / MOD) *
Lucas(m % MOD, n % MOD) % MOD;
}
终
大家和有人的两个名字流传千古。不过另外一个\(\mod p\)大陆又出现了问题,这里\(p\)不是质数,他们能顶住恶魔的进攻吗?有人建议,去东方找着中国剩余定理!!
传送门:
关于C(m,n)%p的故事的更多相关文章
- 背后的故事之 - 快乐的Lambda表达式(一)
快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...
- 2000条你应知的WPF小姿势 基础篇<28-33 WPF启动故事>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- 背后的故事之 - 快乐的Lambda表达式(二)
快乐的Lambda表达式 上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式.知道了它和委托以及普通方法的区别,并且通过测试对比他们之间的性能,然后我们 ...
- UDAD 用户故事驱动的敏捷开发 – 演讲实录
敏捷发展到今天已经在软件行业得到了广泛认可,但大多数敏捷方法都是为了解决某一特定问题而总结出来的特定方法或实践,一直缺乏一个可以将整个开发过程串接起来的成体系的方法.用户故事驱动的敏捷开发(User ...
- iOS系列 基础篇 02 StoryBoard 故事板文件
iOS基础 02 StoryBoard 故事板文件 目录: 1. 故事板的导航特点 2. 故事板中的Scene和Segue 3. 本文最后 在上篇HelloWorld工程中有一个Main.storyb ...
- 前端少侠的ps故事
前端少侠的ps故事 正所谓,码在江湖,身不由己.自21世纪前后端分离,代码分工细化以来,前端与设计的合作也变得越来越重要.有人说,如果前端懂设计的话,工作会更快一点.倘若说我入前端半年能算半个前端少侠 ...
- 【码在江湖】前端少侠的json故事(上)日月第一击
日月第一击 这是我前端生涯第一次和后台对接,其经历真是苦不堪言,多次绝处逢生,柳暗花明,可就是迟迟见不到那条村子.当然,最后我还是完成了这次对接.下面来聊一聊我这白痴一般的经历. 序章 话说天下大势, ...
- 【码在江湖】前端少侠的json故事(下):jsonp的应用
jsonp的应用 话说天下大势,分久必合,合久必分,代码江湖自进入21世纪以来,前后端分离成为了大势所趋,代码分工更为精细,更为深入,而正所谓码在江湖,身不由己,为了更好的实现需求,程序猿们必须不断学 ...
- 【码在江湖】前端少侠的json故事(中)ng的json
ng的json 正所谓"人在江湖,身不由己",在开发之路上前端少侠dk遇到过种种困难,尤其在与后端进行数据对接的时候,不得不逼迫自己以极快的速度去学习和掌握一些奇招怪式,正当他以为 ...
- 初识WEB:输入URL之后的故事
1. 概述2. HTTP请求过程3. 相关性能检测及优化手段4. 浏览器的呈现过程5. 浏览器的呈现引擎6. 引用及延伸阅读 概述 为什么输入www.cnblogs.com之后敲一个回车,浏览器就会显 ...
随机推荐
- tomcat使用所遇到的问题
1.在使用eclipse添加server的时候添加不了tomcat服务器: 如图左图所示,添加按钮已成灰色,无法操作. 解决办法:找到workspace的工作空间->.metadata-> ...
- java:字符串的“+”运算
今天在一篇博客里,意外的看到了一段关于java中对字符串的“+”运算的处理(博客原文:http://blog.csdn.net/yirentianran/article/details/2871417 ...
- cmake 学习笔记(六)
希望这是现阶段阻碍阅读shiboken和PySide源码的涉及cmake的最后一个障碍 ^ _^ 学习 cmake 的单元测试部分 ctest. 简单使用 最简单的使用ctest的方法,就是在 CMa ...
- java学习之动态代理模式
package com.gh.dynaproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Metho ...
- 首届全球RTB(实时竞价)广告DSP算法大赛
首届全球RTB(实时竞价)广告DSP算法大赛 竞赛指南 RTB (Real Time Bidding, 实时竞价) 是近年来计算广告领域最激动人心的进展之一. 它增加了展示广告的透明度与效率, ...
- HDU 4741 Save Labman No.004 2013 ACM/ICPC 杭州网络赛
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4741 题意:给你两条异面直线,然你求着两条直线的最短距离,并求出这条中垂线与两直线的交点. 需要注意的是 ...
- uva--11991 - Easy Problem from Rujia Liu?(sort+二分 map+vector vector)
11991 - Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for e ...
- stm32之USART通信
任何USART通信,需要用到2个对外连接的引脚:RxD,TxD: RxD是输入引脚,用于串行数据接收: TxD是输出引脚,用于串行数据发送: SCLK引脚:发生器时钟输出(同步模式下,异步模式下不需要 ...
- BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )
题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...
- BZOJ 1797: [Ahoi2009]Mincut 最小割( 网络流 )
先跑网络流, 然后在残余网络tarjan缩点. 考虑一条边(u,v): 当且仅当scc[u] != scc[v], (u,v)可能出现在最小割中...然而我并不会证明 当且仅当scc[u] = scc ...