遥远的\(\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\)不是质数,他们能顶住恶魔的进攻吗?有人建议,去东方找着中国剩余定理!!

传送门:

详解
Lucas定理
费马小定理

关于C(m,n)%p的故事的更多相关文章

  1. 背后的故事之 - 快乐的Lambda表达式(一)

    快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...

  2. 2000条你应知的WPF小姿势 基础篇<28-33 WPF启动故事>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

  3. 背后的故事之 - 快乐的Lambda表达式(二)

    快乐的Lambda表达式 上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式.知道了它和委托以及普通方法的区别,并且通过测试对比他们之间的性能,然后我们 ...

  4. UDAD 用户故事驱动的敏捷开发 – 演讲实录

    敏捷发展到今天已经在软件行业得到了广泛认可,但大多数敏捷方法都是为了解决某一特定问题而总结出来的特定方法或实践,一直缺乏一个可以将整个开发过程串接起来的成体系的方法.用户故事驱动的敏捷开发(User ...

  5. iOS系列 基础篇 02 StoryBoard 故事板文件

    iOS基础 02 StoryBoard 故事板文件 目录: 1. 故事板的导航特点 2. 故事板中的Scene和Segue 3. 本文最后 在上篇HelloWorld工程中有一个Main.storyb ...

  6. 前端少侠的ps故事

    前端少侠的ps故事 正所谓,码在江湖,身不由己.自21世纪前后端分离,代码分工细化以来,前端与设计的合作也变得越来越重要.有人说,如果前端懂设计的话,工作会更快一点.倘若说我入前端半年能算半个前端少侠 ...

  7. 【码在江湖】前端少侠的json故事(上)日月第一击

    日月第一击 这是我前端生涯第一次和后台对接,其经历真是苦不堪言,多次绝处逢生,柳暗花明,可就是迟迟见不到那条村子.当然,最后我还是完成了这次对接.下面来聊一聊我这白痴一般的经历. 序章 话说天下大势, ...

  8. 【码在江湖】前端少侠的json故事(下):jsonp的应用

    jsonp的应用 话说天下大势,分久必合,合久必分,代码江湖自进入21世纪以来,前后端分离成为了大势所趋,代码分工更为精细,更为深入,而正所谓码在江湖,身不由己,为了更好的实现需求,程序猿们必须不断学 ...

  9. 【码在江湖】前端少侠的json故事(中)ng的json

    ng的json 正所谓"人在江湖,身不由己",在开发之路上前端少侠dk遇到过种种困难,尤其在与后端进行数据对接的时候,不得不逼迫自己以极快的速度去学习和掌握一些奇招怪式,正当他以为 ...

  10. 初识WEB:输入URL之后的故事

    1. 概述2. HTTP请求过程3. 相关性能检测及优化手段4. 浏览器的呈现过程5. 浏览器的呈现引擎6. 引用及延伸阅读 概述 为什么输入www.cnblogs.com之后敲一个回车,浏览器就会显 ...

随机推荐

  1. 「OC」点语法和成员变量的作用域

    一.点语法 (一)认识点语法 声明一个Person类: 1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObje ...

  2. C#线程应用实例(part1) 之 BeginInvoke和EndInvoke

    最近这个公司是做 winfrom 开发的 , 这段时间就好好的学学WCF , 公司框架什么的自己去琢磨! 这里主要写一些 winfrom 中 用到的一些陌生 技术 1.BeginInvoke  以前B ...

  3. OSX/iOS 播放系统声音

    方法1: 系统会自带了些声音,有时候一些操作用必要自己播放一下声音提醒一下,用bash的直接say something就ok了,写代码的时候呢?原来很简单的,一句: [[NSSound soundNa ...

  4. java中printf中用法详解

    目前printf支持以下格式: %c 单个字符 %d 十进制整数 %f 十进制浮点数 %o 八进制数 %s 字符串 %u 无符号十进制数 %x 十六进制数 %% 输出百分号% printf的格式控制的 ...

  5. javascript模块加载框架seajs详解

    SeaJS是一个遵循commonJS规范的javascript模块加载框架,可以实现javascript的模块化开发和模块化加载(模块可按需加载或全部加载).SeaJS可以和jQuery完美集成,使用 ...

  6. Xamarin.Android开发实践(一)

    原文:Xamarin.Android开发实践(一) 一.准备工作 1.创建一个空的解决方案,并命名为Phoneword 2.右击解决方案 新建->新建项目 并命名为Phoneword_Droid ...

  7. 数据切分——MySql表分区概述

    定义:         表的分区指根据可以设置为任意大小的规则,跨文件系统分配单个表的多个部分.实际上,表的不同部分在不同的位置被存储为单独的表.用户所选择的.实现数据分割的规则被称为分区函数,这在M ...

  8. Muduo 网络编程示例之零:前言

    陈硕 (giantchen_AT_gmail)Blog.csdn.net/Solstice Muduo 全系列文章列表: http://blog.csdn.net/Solstice/category/ ...

  9. BZOJ 1324: Exca王者之剑

    1324: Exca王者之剑 Description Input 第一行给出数字N,M代表行列数.N,M均小于等于100 下面N行M列用于描述数字矩阵 Output 输出最多可以拿到多少块宝石 Sam ...

  10. ligh@local-host$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.3

    ligh@local-host$ ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.3