组合数一种是OI中比较常用的知识

除了实际的分析之外,我们要考虑的,就是如何快速计算组合数

下面介绍几种常用的计算组合数的方法

朴素公式法

顾名思义,直接套公式
int C(int n,int m){int ans=1;for(int i=1;i<=m;i++) ans=ans*(n-m+i)/i;return ans;
}

如果要对质数P取模,就是这样:

int C(int n,int m){int ans=1;for(int i=1;i<=m;i++) ans=(LL)ans*(n-m+i)*inverse(i)%P;return ans;
}
其中inverse是i对P的逆元,如果P是质数inverse(i)=i^(P-2)   【费马小定理得】,否则用exgcd求出【欧拉定理也行】

递推式法

C(n,m)=C(n-1,m-1)+C(n-1,m)
边界:C(i,0)=C(i,i)=1
这个递推式用到了动态规划的思想,对于第m个物品,有取和不取两种情况
可以在O(n^2)的时间内算出所有的C(n,m)
void cal(){C[0][0]=1;for(int i=1;i<=n;i++){C[i][0]=C[i][i]=1;for(int j=1;j<=(i>>1);j++){C[i][j]=C[i][i-j]=(C[i-1][j-1]+C[i-1][j])%P;}}
}

Lucas定理

对于n和m比较大(<=10^18)的组合数,就要用到LUCAS定理啦

Lucas定理解决的是n,m比较大而p是小于100000质数

简而言之就是Lucas(n,m)=C(n%p,m%p)*Lucas(n/p,m/p)%p;

其中组合数C是用任意一种计算10五次方内取模的组合数计算

比如可以预处理阶乘fac[i],然后直接C(n,m)=fac[n]*quickpow(fac[n-m]*fac[m],p-2)%p;

或者O(n)套公式直接算也可以

要注意n可能小于m,因为是取模后的结果,这个时候返回0【不然会RE】

LL Lucas(LL n,LL m){  if(n<m||!m) return 1;  return C(n%P,m%P)*Lucas(n/P,m/P)%P;
} 

配合Lucas定理,由于n和m都在10^5范围内,使用预处理阶乘的方法再好不过了:

预处理阶乘法

其实就是直接套公式,只不过使用了 预处理阶乘+逆元,查询复杂度O(log100000),非常低

void cal(){  fac[0]=1;  for(int i=1;i<=P;i++) fac[i]=fac[i-1]*i%P;
}  inline LL qpow(LL a,LL b){  LL ans=1;  for(;b;b>>=1,a=a*a%P) if(b&1) ans=ans*a%P;return ans;
}  inline LL C(LL n,LL m){  if(n<m) return 0;  return fac[n]*qpow(fac[n-m]*fac[m]%P,P-2)%P;
}  

转载于:https://www.cnblogs.com/Mychael/p/8282883.html

组合数的几种计算方法相关推荐

  1. R语言中如何计算C-Statistics?几种计算方法详解

    R语言中如何计算C-Statistics?几种计算方法详解 目录 R语言中如何计算C-Statistics? #包导入 #数据加载编码

  2. 置信区间(Confidence Intervals)是什么?如何计算置信区间?置信区间的两种计算方法是什么?二值样本置信区间如何计算?如何基于bootstrap抽样进行置信区间计算?

    置信区间(Confidence Intervals)是什么?如何计算置信区间?置信区间的两种计算方法是什么?二值样本置信区间如何计算?如何基于bootstrap抽样进行置信区间计算? 目录 置信区间( ...

  3. PCL点云处理之点云质心的三种计算方法(七十六)

    PCL点云处理之点云质心的三种计算方法(七十六) 一.质心? 二.算法实验 1.代码 2.效果 一.质心? 就计算某块点云坐标均值,可以调库,也可以自己算,easy 二.算法实验 1.代码 代码如下( ...

  4. 【算法】计算组合数的四种常用方法

    [算法]计算组合数的四种常用方法 算法一:Cab=Ca−1b−1+Ca−1bC_{a}^{b}=C_{a-1}^{b-1}+C_{a-1}^{b}Cab​=Ca−1b−1​+Ca−1b​ 解析: Ca ...

  5. TIA博途中累计流量的两种计算方法示例

    TIA博途中累计流量的两种计算方法示例 如下图所示,首先,我们要了解累计流量的含义: 即t1至t2时刻,对瞬时流量求定积分, 由上图可知,t1至t2的定积分,即蓝色部分的面积,那么直接求这个面积是有难 ...

  6. 四分位数的两种计算方法

    关于四分位数的两种求法 在数据导论课上,我们学习了如何求解四分位数的方法,其实操作起来也不难先用 (n+1) / 4 * i 计算出四分位数的位置,再求出该位置上的数的值即可.如一组数据 [1,3,6 ...

  7. 如何理解LTV(单个用户整个生命周期价值)的5种计算方法?

    前言:本文内容以游戏产品为基础进行讲解,内容为LTV的5种计算方法. 定义:LTV值单个用户整个生命周期所产生的价值. 说明:在谈论LTV的计算方法时,容易混淆的点:指标限定的时间范围.LTV的每种计 ...

  8. 组合数C(n,m)的四种计算方法

    转载自 组合c(m,n)的计算方法    问题:求解组合数C(n,m),即从n个相同物品中取出m个的方案数,由于结果可能非常大,对结果模10007即可. 共四种方案.ps:注意使用限制. 方案1: 暴 ...

  9. 组合数的几种常见计算方法

    加法递推 : o ( n ∗ n ) o(n*n) o(n∗n) 公式: C ( m n ) C\tbinom{m}{n} C(nm​) = C ( m n − 1 ) C\tbinom{m}{n-1 ...

最新文章

  1. Spring 如何在一个事务中开启另一个事务?
  2. C++中一些类和数据结构的大小的总结
  3. [Js-Spring]Spring与IoC(控制反转,Inversion of Control)
  4. Clonezilla制作镜像时报错:extfsclone.c:bitmap free count err解决办法
  5. 简易mysql优化_优化 MySQL:简单三个技巧
  6. springboot使用PageHelper实现分页
  7. 年终总结 | 从Oracle到MySQL大家最关注的竟然是...
  8. SAP License:ReportPainter报表显示JPY等无小数位货币时少两位
  9. linux+模块与设备关系,linux内核设计与实现读书笔记——设备和模块
  10. android 自动打包工具,AutopackingAndroid
  11. 萌新误入AI歧途怎么办?MIT博士小哥哥给你指条明路
  12. c语言用数组实现大数加减,c语言版大数计算器(实现大数的加减乘除运算,已更新源代码)...
  13. Android音频系统之音频框架
  14. 第十六届“振兴杯”计算机网络管理员赛项理论参考题库(2)多选
  15. 分布式数据库原理解析
  16. 【Python案例】Python实现垃圾分类APP(附带微信小程序)
  17. 快速分区MBR和GUID的区别
  18. pandas 数据怎样实现行间计算
  19. 使用express脚手架创建项目
  20. Java学习笔记——程序逻辑控制

热门文章

  1. win10应用闪退解决方法
  2. ASP计算周开始和一年有多少周及某年第一周开始日期
  3. 建立大数据分析能力需四大要素
  4. 2021数据库MYSQL语句梳理(Navicat)
  5. 华硕双路服务器主板装系统,华硕双路服务器主板Z8PE-D12X
  6. 治疗口腔溃疡的穴位按摩方法
  7. Latex表格标题左对齐,并且table加粗
  8. 新特效火爆抖音!各路神仙齐唱《蚂蚁呀嘿》,网友:短短几秒需一生来治愈
  9. Django微信抢票大作业总结
  10. 如何改善毛孔粗大,学养颜心经改善毛孔粗大