求C(n,m)%mod的方法总结

1.当n,m都非常小的时候能够利用杨辉三角直接求。
C(n,m)=C(n-1,m)+C(n-1,m-1)。

2.利用乘法逆元。
乘法逆元:(a/b)%mod=a*(b^(mod-2)) mod为素数。
逆元能够利用扩展欧几里德或欧拉函数求得:

 1).扩展欧几里德:b*x+p*y=1 有解,x就是所求2).费马小定理:b^(p-1)=1(mod p),故b*b^(p-2)=1(mod p),所以x=b^(p-2)

1. n!/(m!*(n-m)! =x%p ,先对算出n!、m!

、(n-m)!对p取模的余数。就转换为a/b=x%p;由于p为素数。所以等价于bx+py=a;然后用扩展的欧几里得定理算出 bx’+py’=1的解。x=x’*a,就得到了终于的x的值,即C(m,n)%p得值。

2.逆元 事实上假设mod是素数 则b的逆元事实上就是b^(mod-2)
也就是 (m!(n-m)!)的逆元为 (m!(n-m)!)p-2 ;

int inv(int a) {   //return fpow(a, MOD-2, MOD);  return a == 1 ?

1 : (long long)(MOD - MOD / a) * inv(MOD % a) % MOD; } LL C(LL n,LL m) { if(m < 0)return 0; if(n < m)return 0; if(m > n-m) m = n-m; LL up = 1, down = 1; for(LL i = 0 ; i < m ; i ++){ up = up * (n-i) % MOD; down = down * (i+1) % MOD; } return up * inv(down) % MOD; }

3.当n和m比較大,mod是素数且比較小的时候(10^5左右)。通过Lucas定理计算

Lucas定理:A、B是非负整数,p是质数。A B写成p进制:A=a[n]a[n-1]…a[0]。B=b[n]b[n-1]…b[0]。

则组合数C(A,B)与C(a[n],b[n])C(a[n-1],b[n-1])…*C(a[0],b[0]) mod p同余
即:Lucas(n,m,p)=C(n%p,m%p)*Lucas(n/p,m/p,p)

#include<iostream>
//#include<algorithm>
using namespace std;
typedef long long ll;
int quick_power_mod(int a,int b,int m){//pow(a,b)%mint result = 1;int base = a;while(b>0){if(b & 1==1){result = (result*base) % m;}base = (base*base) %m;b>>=1;}return result;
}
//计算组合数取模
ll comp(ll a, ll b, int p) {//composite num C(a,b)%pif(a < b)   return 0;if(a == b)  return 1;if(b > a - b)   b = a - b;int 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*quick_power_mod(cb, p - 2, p)) % p;return ans;
}
ll lucas(ll n, ll m, ll p) {ll ans = 1;while(n&&m&&ans) {ans = (ans*comp(n%p, m%p, p)) % p;//also can be recusiven /= p;m /= p;}return ans;
}
int main(){ll m,n;while(cin>>n>>m){cout<<lucas(n,m,10007)<<endl;}return 0;
}

C(n % mod, m % mod) % mod; 假设太大还是利用上面的逆元来处理。

半预处理
由于Lucas定理保证了阶乘的数均小于p,所以能够讲全部的阶乘先预处理,优化C(n,m)
mod的要求:p<10^6,且为素数
有效范围:1<=n,m<=10^9

//半预处理
const ll MAXN = 100000;
ll fac[MAXN+100];
void init(int mod)
{  fac[0] = 1;  for (int i=1; i<mod; i++){  fac[i] = fac[i-1] * i % mod;  }
}  //半预处理逆元求C(n。m)%mod
ll C(ll n, ll m)
{  if ( m>n ) return 0;  return fac[n] * (GetInverse(fac[m]*fac[n-m], mod)) % mod;
}  

4.另一种就是分解质因子。这个比較麻烦。
http://www.mamicode.com/info-detail-621758.html

[组合数]求组合数的几种方法总结相关推荐

  1. 求组合数(四种方法)

    文章目录 求组合数(四种方法) 递推(杨辉三角) 快速幂+乘法逆元 卢卡斯定理 高精度组合数 求组合数(四种方法) 文章首发于我的个人博客:欢迎大佬们来逛逛 递推(杨辉三角) 对于求一个数字的组合数: ...

  2. 【数论】求组合数的四种方法

    组合数的常用公式 零.纯暴力法 根据第一个公式,将的分子和分母求出,再相除即可. 适用范围:n,m较小的情况下. 时间复杂度: 第一种部分代码如下: for(int i = n; i >= n ...

  3. 【POJ - 1942 】Paths on a Grid (组合数学,求组合数的无数种方法)

    题干: Imagine you are attending your math lesson at school. Once again, you are bored because your tea ...

  4. 求组合数(不同类型的组合数C++)

    求组合数有许多种不同的算法,要根据不同的数据量大小选择不同的算法 类型1 给定 n 组询问,每组询问给定两个整数 a,b,请你输出 Cba mod(109+7)的值. 输入格式 第一行包含整数 n. ...

  5. c 语言 组合数,C++中求组合数的各种方法总结详解

    [问题]      组合问题 问题描述:找出从自然数1.2.... .n中任取r个数的所有组合.例如n=5,r=3的所有组合为: 1,2,3 1,2,4 1,3,4 2,3,4 1,2,5 1,3,5 ...

  6. python 求组合数最快方法_python求二项式系数的几种方法及性能对比

    最近研究了python求二项式系数的几种方法,对比了一下他们的速度 1. 利用阶乘简洁求 #普通阶乘 def fact(n): if n == 0: return 1 else: return n*f ...

  7. 计算组合数的几种方法总结

    前言 组合数就是 Cmn C n m C_n^m,是排列组合中非常重要的一部分,最近做到了几道与计算组合数有关的题,想在此总结一下如何编程计算组合数. 某位大佬在我之前也写过类似的文章,这是他的博客: ...

  8. 算法 - 数学 - 组合数 - 隔板法求组合数

    一.求组合数 二.隔板法 隔板法是組合數學的方法,用來處理n個無差別的球放進k個不同的盒子的問題.可一般化為求不定方程的解數,並利用母函數解決問題. 隔板法與插空法的原理一樣. 应用隔板法必须满足3个 ...

  9. 算法刷题-数论-组合数、快速幂、逆元、递推求组合数、逆元求组合数

    文章目录 acwing885. 求组合数 I(递推:数据范围:2000) acwing875. 快速幂(a的k次方 模 b) acwing876. 快速幂求逆元 acwing886. 求组合数 II( ...

最新文章

  1. highstock 只显示所有 不显示 月_小米34寸曲面显示器深度体验 办公体验极佳 但是还有个大弱点...
  2. 如何打造规范的开源项目workflow
  3. vmware centos7 扩展容量
  4. Vue的Props属性概述
  5. 如何处理SAP Fiori Launchpad错误消息:Could not start the app due to a configuration problem
  6. 深度学习资料汇总(满满的干货)
  7. 书评:精通Lambda:多核世界中的Java编程
  8. Angular CLI 安装
  9. 2021最新Python量化A股投资必赚策略
  10. 告别30元!喜茶承诺今年绝不涨价:不再推29元以上产品
  11. WiFi(网络)调试Android手机
  12. 华为手机耳机sws音效是什么_【小知识】:华为SWS音效介绍。
  13. Java基础知识点回顾
  14. docker装LibreELEC_如何在LibreELEC上安装Entware?
  15. 通过iis发布网站、并添加ssl证书
  16. 业余设计不求人,30秒AI快速制作LOGO
  17. Windows CE SDHC驱动简析(1)-驱动架构(基于WinCE5.0 SMDK2410 BSP的SDHC驱动)
  18. buct哥德巴赫猜想
  19. 修改IE临时文件夹(缓存)路径
  20. python甲骨文培训

热门文章

  1. 我们不应歧视任何编程语言,她们都是萌娘!(有图有真相)
  2. 程序员面试题精选100题(23)-跳台阶问题[算法]
  3. 【人脸识别】人脸验证算法Joint Bayesian详解及实现(Python版)
  4. Qt安装和QML HelloWord程序
  5. 人工智能:第五章 计算智能(2)
  6. Machine Learning week 7 quiz: programming assignment-Support Vector Machines
  7. 二叉排序树的建立、先序/中序/后序遍历、查找
  8. 递归求解1~9组成的特殊9位整数
  9. Dockerfile构建PHP镜像
  10. 腾讯开放TAPD、持续集成平台等核心研发工具,加速AI落地