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

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

对于C(n, m) mod p。这里的n,m,p(p为素数)都很大的情况。就不能再用C(n, m) = C(n - 1,m) + C(n - 1, m - 1)的公式递推了。

于是就得到了Lucas定理:C(n,m)%p=C(n/p,m/p)*C(n%p,m%p)%p

根据:

已知(a, p) = 1,则 ap-1 ≡ 1 (mod p),  所以 a*ap-2 ≡ 1 (mod p)。

也就是 (m!(n-m)!)的逆元为 (m!(n-m)!)p-2 ;

所以就用快速幂就可以解决了,也可以用扩展欧几里得算法,也可以了。

typedef long long LL;using namespace std;LL exp_mod(LL a, LL b, LL p) {    LL res = 1;    while(b != 0) {        if(b&1) res = (res * a) % p;        a = (a*a) % p;        b >>= 1;    }    return res;}LL Comb(LL a, LL b, LL p) {    if(a < b)   return 0;    if(a == b)  return 1;    if(b > a - b)   b = a - b;    LL ans = 1, ca = 1, cb = 1;    for(LL i = 0; i < b; ++i) {        ca = (ca * (a - i))%p;        cb = (cb * (b - i))%p;    }    ans = (ca*exp_mod(cb, p - 2, p)) % p;    return ans;}LL Lucas(int n, int m, int p) {     LL ans = 1;     while(n&&m&&ans) {        ans = (ans*Comb(n%p, m%p, p)) % p;        n /= p;        m /= p;     }     return ans;}int main() {    Read();    int n, m, p;    while(~scanf("%d%d%d", &n, &m, &p)) {        printf("%lld\n", Lucas(n, m, p));    }    return 0;}

这是一个费马小定理的代码

转载于:https://www.cnblogs.com/fengzhiyuan/p/7411075.html

你可能感兴趣的文章
socket.io 消息发送
查看>>
C# 两个datatable中的数据快速比较返回交集或差集
查看>>
关于oracle样例数据库emp、dept、salgrade的mysql脚本复杂查询分析
查看>>
一些有趣的代码
查看>>
Major Performance Impacts
查看>>
读《图解HTTP》有感-(返回结果的HTTP状态码)
查看>>
操作数栈
查看>>
转:文本分类问题
查看>>
tensorflow_python中文手册
查看>>
Vs2012在Linux应用程序开发(3):加入新平台hi3516
查看>>
adb shell am 的用法
查看>>
实现自动点击
查看>>
MVP开发模式的理解
查看>>
Unity多开的方法
查看>>
File类中的list()和listFiles()方法
查看>>
我的VS CODE插件配置 主要针对.NET和前端插件配置
查看>>
关于js中的事件
查看>>
一致性哈希算法运用到分布式
查看>>
决策树和随机森林->信息熵和条件熵
查看>>
iOS10 UI教程视图和子视图的可见性
查看>>