当前位置: 首页 > article >正文

经典算法 求C(N, K) % mod,保证mod是质数

求C(N, K) % mod,保证mod是质数

问题描述

给你三个整数N,K,mod保证mod是一个质数,求组合数C(N, K) % mod。

输入描述

输入有多组,输入第一行为两个整数Tmod。接下来2 - T + 1行,每行输入NK

输出描述

每一组输入,输出C(N, K) % mod。

输入示例

9 1000003
6 4
7 5
3 2
10 5
100 50
1000 500
10000 5000
100000 50000
1000000 500000

输出示例

15
21
3
252
440004
175726
737315
781911
375001

c++代码(乘法逆元)

这种方法大致可以处理N,K<= 1000000,mod <= 1000000009。

保证mod为质数,用费马小定理求逆元。

#include<bits/stdc++.h>using namespace std;typedef __int128_t ll;//防止数据溢出long long T, N, K, mod;//保证mod是质数
vector<ll> jiecen;ll fastPow(ll a, ll b, ll mod) {//返回a^b % modif (b == 0) return 1 % mod;if (b == 1) return a % mod;ll k = fastPow(a, b / 2, mod);if (b % 2 == 0) return (k * k) % mod;else return (((k * k) % mod) * a) % mod;
}ll mod_inverse(ll A, ll mod) { return fastPow(A, mod - 2, mod); }//求A % mod 的逆元ll cnk(ll N, ll K, ll mod) { return (jiecen[N] * mod_inverse((jiecen[K] * jiecen[N - K]) % mod, mod)) % mod; }//返回组合数C(N, K) % modint main() {cin >> T >> mod;jiecen = vector<ll>(1000001, 1);//预处理阶乘for (int i = 1; i <= 1000000; i++) jiecen[i] = (jiecen[i - 1] * i) % mod;while(T--) {cin >> N >> K;cout << (long long)cnk(N, K, mod) << endl;}return 0;
}//by wqs

c++代码(卢卡斯定理)

大致可以处理N,K <= 1 * 10^18, mod <= 1000000。

卢卡斯递归过程中可能会出现N < K,这个时候cnk函数要返回0

#include<bits/stdc++.h>using namespace std;typedef __int128_t ll;vector<ll> jiecen;
long long T, N, K, mod;ll fastPow(ll a, ll b, ll mod) {//返回a^b % modif (b == 0) return 1 % mod;if (b == 1) return a % mod;ll k = fastPow(a, b / 2, mod);if (b % 2 == 0) return (k * k) % mod;else return (((k * k) % mod) * a) % mod;
}ll mod_inverse(ll A, ll mod) { return fastPow(A, mod - 2, mod); }//求A % mod 的逆元ll cnk(ll N, ll K, ll mod) { return N >= K ? (jiecen[N] * mod_inverse((jiecen[K] * jiecen[N - K]) % mod, mod)) % mod : 0; }//返回组合数C(N, K) % modll Lucas(ll N, ll K, ll mod) { return K == 0 ? 1 : (cnk(N % mod, K % mod, mod) * Lucas(N / mod, K / mod, mod)) % mod; }int main() {cin >> T >> mod;jiecen = vector<ll>(mod, 1);for (int i = 1; i <= mod - 1; i++) jiecen[i] = (__int128_t(jiecen[i - 1]) * i) % mod;while(T--) {cin >> N >> K;cout << (long long)Lucas(N, K, mod) << endl;}return 0;
}//by wqs
http://www.lryc.cn/news/2378334.html

相关文章:

  • 【LeetCode 热题 100】二叉树的最大深度 / 翻转二叉树 / 二叉树的直径 / 验证二叉搜索树
  • 关于软件测试开发的一些有趣的知识
  • uni-app 开发HarmonyOS的鸿蒙影视项目分享:从实战案例到开源后台
  • 售前工作.工作流程和工具
  • GPU与NPU异构计算任务划分算法研究:基于强化学习的Transformer负载均衡实践
  • 学习ai课程大纲
  • 基于CentOS7制作OpenSSL 1.1的RPM包
  • 数据分析_Python
  • TCP/UDP协议原理和区别 笔记
  • 深入浅出:C++数据处理类与计算机网络的巧妙类比
  • 【滑动窗口】LeetCode 209题解 | 长度最小的子数组
  • 在RK3588上使用NCNN和Vulkan加速ResNet50推理全流程
  • 【ant design】ant-design-vue 4.0实现主题色切换
  • Android 图片自动拉伸不变形,点九
  • 电子电路:什么是色环电阻器,怎么识别和计算阻值?
  • LeetCode Hot100刷题——轮转数组
  • Python绘制南丁格尔玫瑰图:从入门到实战
  • 概率与期望总结
  • 炼丹学习笔记3---ubuntu2004部署运行openpcdet记录
  • 深入解析BGP路由反射器与联邦:突破IBGP全连接限制的两种方案
  • QT设置MySQL驱动
  • String的一些固定程序函数
  • 3.2/Q2,Charls最新文章解读
  • 大麦(Hordeum vulgare)中 BAHD 超家族酰基转移酶-文献精读129
  • docker迅雷自定义端口号、登录用户名密码
  • 中国30米年度土地覆盖数据集及其动态变化(1985-2022年)
  • 3D个人简历网站 5.天空、鸟、飞机
  • STM32IIC实战-OLED模板
  • Sparse4D运行笔记
  • Redis设计与实现——分布式Redis