Cnm

下面是对四个不同数量级的处理

一、1 <= n , m <= 20

可以直接暴力阶乘求解

ll gcd(ll m,ll n){     //计算最大公约数return n ? gcd(n,m%n) : m;
}ll f(ll n)
{ll ret=1;for(ll i=1;i<=n;i++)    ret*=i;return ret;
}ll C(ll n,ll m)    //计算组合数
{ll fz=f(n);    //分子ll fm=f(m)*f(n-m);    //分母ll z=gcd(fz,fm);    //约分ll ans=(fz/z)/(fm/z);
}

不难看出,里面有很多重复计算的值,比如 m! 。
所以我们还可以小小的优化一下。
优化点:
①根据组合数(Cnm)的性质,当 m > n/2 时,效果与 n-m 一致。
②分子、分母去重。
分子:n * (n-1) * (n-2) …… 3 * 2 * 1
分母:[ m * (m-1) … 2 * 1 ] * [ (n-m) * (n-m-1) … 2 * 1 ]
加粗表示可以约分
③在计算的过程中,也可以不断地除去能除的数。比如 2 3 ……

long long cnm(int n,int m)
{long long s = 1;int k = 1;if(m > n/2)m = n-m;for(int i=n-m+1;i<=n;i++){s *= (long long)i;while(k<=m && s%k == 0){s /= (long long)k;k++;}}return s;
}

【注意】仍只能计算小范围!

二、数量级:103

由高中数学知识可以知道,组合数实际上就是杨辉三角,那我们就可以用递推式。

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long ll;
const ll N=2005;
ll C[N][N];void init()
{for(ll i=0;i<N;i++)for(ll j=0;j<=i;j++)if(!j)  C[i][j]=1;else    C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
}int main()
{init();ll a,b;cin>>a>>b;cout<<C[a][b]<<endl;return 0;
}

三、数量级:10^5

预处理阶乘 + 逆元

数量级已经超过 long long 的范围了,而且分数不能直接取模,所以我们采用逆元处理。
先用数组存储每一个的阶乘结果和逆元结果。

不开 infac[] 数组也可以,直接求就是了。(见下面被注释掉的代码)

逆元不会点这里

原题链接

AC代码

#include <bits/stdc++.h>
#include <iostream>
#define mod 1000000007
using namespace std;
typedef long long ll;
const ll N=1e5+5;
ll fac[N],infac[N];ll fastpower(ll base,ll power)
{ll ret=1;while(power){if(power&1)    ret=ret*base%mod;power>>=1;base=base*base%mod;}return ret;
}void init()
{fac[0]=infac[0]=1;for(ll i=1;i<N;i++){fac[i]=fac[i-1]*i%mod;    //阶乘infac[i]=infac[i-1]*fastpower(i,mod-2)%mod;    //逆元//不想要 infac[] 可以把这行删掉}
}ll Cc(ll n,ll m){    //组合数return fac[n]*infac[m]%mod*infac[n-m]%mod;
}//ll Cc(ll n,ll m)    //组合数{//    return fac[n]*fastpower(fac[m]*fac[n-m]%mod,mod-2)%mod;
//}int main()
{init();int t;scanf("%d",&t);while(t--){ll n,m,k,q;scanf("%lld%lld%lld%lld",&n,&m,&k,&q);if(k>n)    printf("0\n");else{ll fz=Cc(n,k);ll fm=Cc(n+m,k);fz=fastpower(fz,q)%mod;fm=fastpower(fm,q)%mod;ll ans=(fz*fastpower(fm,mod-2))%mod;printf("%lld\n",ans);   }}return 0;
}

四、数量级:10^18

这种数量级只能用卢卡斯定理

【证明】
一位大佬的证明,很简洁
也是大佬的,可以与上面补充使用

但适合测试组数较少的,否则容易超出题目的内存限制

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long ll;ll fastpower(ll base,ll power)
{ll ret=1;while(power){if(power&1) ret=ret*base%mod;power>>=1;base=base*base%mod;}return ret;
}ll C(ll a,ll b)
{if(b>a) return 0;ll res=1;for(ll i=1,j=a;i<=b;i++,j--){res=res*j%mod;res=res*fastpower(i,mod-2)%mod;}return res;
}ll Lucas(ll a,ll b)
{return C(a%mod,b%mod)*Lucas(a/mod,b/mod)%mod;
}void sovle()
{ll n,m,k,q;cin>>n>>m>>k>>q;ll fz=Lucas(n,k);ll fm=Lucas(n+m,k);fz=fastpower(fz,q);fm=fastpower(fm,q);ll ans=(fz*fastpower(fm,mod-2)%mod)%mod;cout<<ans<<endl;
}int main()
{int n;scanf("%d",&n);while(n--)  solve();return 0;
}

欢迎指正修改。

【学习笔记】处理极大组合数相关推荐

  1. MySQL 索引学习笔记

    MySQL 索引学习笔记 索引基本概念 索引优点 B-Tree 索引 基本原理 使用场景 使用限制 哈希索引 基本原理 使用限制 自适应哈希索引 处理哈希冲突 相关面试题 高性能索引策略 独立的列 前 ...

  2. 算法学习 (门徒计划)3-3 深搜(DFS)与广搜(BFS)及经典问题 学习笔记

    算法学习 (门徒计划)3-3 深搜(DFS)与广搜(BFS)及经典问题 学习笔记 前言 深搜与广搜 搜索的核心概念 问题求解树 搜索剪枝和优化 问题求解树的状态 对比深搜与广搜 DFS-深度(deep ...

  3. 容器云原生DevOps学习笔记——第三期:从零搭建CI/CD系统标准化交付流程

    暑期实习期间,所在的技术中台-效能研发团队规划设计并结合公司开源协同实现符合DevOps理念的研发工具平台,实现研发过程自动化.标准化: 实习期间对DevOps的理解一直懵懵懂懂,最近观看了阿里专家带 ...

  4. 《繁凡的深度学习笔记》前言、目录大纲 一文让你完全弄懂深度学习所有基础(DL笔记整理系列)

    <繁凡的深度学习笔记>前言.目录大纲 (DL笔记整理系列) 一文弄懂深度学习所有基础 ! 3043331995@qq.com https://fanfansann.blog.csdn.ne ...

  5. 一文弄懂元学习 (Meta Learing)(附代码实战)《繁凡的深度学习笔记》第 15 章 元学习详解 (上)万字中文综述

    <繁凡的深度学习笔记>第 15 章 元学习详解 (上)万字中文综述(DL笔记整理系列) 3043331995@qq.com https://fanfansann.blog.csdn.net ...

  6. 【学习笔记】线性代数全家桶(在编程竞赛中的应用)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00. 矩阵 0x01. 矩阵 0x02. 矩阵的加法与数量乘法 0x03. 矩阵乘法 0x ...

  7. StatQuest学习笔记23——RNA-seq简介

    StatQuest学习笔记23--RNA-seq简介 前言--主要内容 这篇笔记是StatQuest系列笔记的第58节,主要内容是讲RNA-seq的原理.StatQuest系列教程的58到62节是协录 ...

  8. BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题学习笔记】

    2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec  Memory Limit: 259 MB Submit: 9894  Solved: 4561 [Su ...

  9. react学习笔记1--基础知识

    什么是react A JAVASCRIPT LIBRARY FOR BUILDING USER INTERFACES[React是一个用于构建用户界面的JavaScript库.] React之所以快, ...

  10. oracle数据库修改写入状态,【学习笔记】Oracle oradebug 使用oradebug修改数据库SCN方法案例...

    天萃荷净 使用oradebug修改数据库scn,使用oradebug修改数据库scn的案例. 这里也做了两个测试,发现该功能确实很巧妙,通过修改内存中的scn值,然后写入控制文件和数据文件,实现修改s ...

最新文章

  1. 「每日分享」CPU Cache 与缓存行
  2. Javaweb 项目内所有页面都是404问题
  3. Asp.Net MVC 使用FileResult导出Excel数据文件
  4. 探索多媒体开发最新最佳实践,我们在深圳等你
  5. ../configure: /bin/sh^M: bad interpreter: No such file or directory
  6. [Leedcode][JAVA][按摩师][动态规划]
  7. python创建数据库字数不限制_textarea字数限制方法一例
  8. 47 SD配置-销售凭证设置-激活项目类别的定价
  9. 【单片机实验】矩阵键盘
  10. Keil 中的预处理命令const
  11. 解析OA系统易用性的价值和意义
  12. 安信可ESP8266开发环境搭建
  13. Google kickstart 2013 Practice Round Captain Hammer 题解
  14. 移动端H5页面编辑器开发实战--原理结构篇
  15. 判断BIOS的启动模式和磁盘分区格式
  16. TIG监控平台监控docker容器
  17. java实现退出重启后保存_JAVA实现关机、重启等
  18. 蒙特卡罗树搜索法c语言,蒙特卡罗方法的计算方法
  19. php中``反引号的作用
  20. Microduino-W5500

热门文章

  1. 快递100Python爬虫(一)
  2. ppt设置外观样式_如何改变幻灯片中文本的外观格式?
  3. 计算机网络——应用层(http、SMTP、DNS)
  4. 阿里云学生版服务器从零搭建教程
  5. 用python实现二次函数的求导、求梯度、Hesse矩阵、求模
  6. 游戏联运系统在应对DDOS攻击方面应如何应对
  7. openlayers前端地图框架
  8. 2022年江西理工大学软件工程学院程序设计竞赛
  9. 用Vue写一个简单好看的菜单组件(Vue实战系列)
  10. 免安装Oracle客户端就能使用pl/sql developer