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

经典算法 求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.dtcms.com/a/197417.html

相关文章:

  • Java面向对象基础学习笔记
  • 字体样式集合
  • AI:人形机器人一定是人的形状吗?
  • 题单:汉诺塔问题
  • 深入了解 VPC 端点类型 – 网关与接口
  • Java的线程通信机制是怎样的呢?
  • Java、ssm(AI) 2025/5/17
  • MySQL 中 JOIN 和子查询的区别与使用场景
  • 《棒球万事通》球类运动有哪些项目·棒球1号位
  • 5.2.1_2二叉树的性质
  • Autosar Nvm下电存储实现方式-基于ETAS工具
  • Codeforces Round 1024 (Div.2)
  • Mysql数据库之集群进阶
  • 日志系统**
  • 在WSL中的Ubuntu发行版上安装Anaconda、CUDA、CUDNN和TensorRT
  • 深度学习(第3章——亚像素卷积和可形变卷积)
  • 从零开发 1688 数据接口:商品详情页实时采集 API 接入详解
  • VC++6.0分步执行常见问题及解决方案
  • Redis——三大策略
  • TTS:F5-TTS 带有 ConvNeXt V2 的扩散变换器
  • TXT记录解析技术深度解析与应用实践
  • 阿里巴巴视觉生成大模型1.2.1版本深度部署指南
  • 【原创】基于视觉大模型gemma-3-4b实现短视频自动识别内容并生成解说文案
  • Data whale LLM universe
  • Unable to get end effector tips from jmg
  • Linux zip、unzip 压缩和解压
  • 医疗大模型技术演进与行业应用全景
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(23):受身形
  • c/c++的opencv模糊
  • 【leetcode】2900. 最长相邻不相等子序列 I