求组合数的O(n^2)和O(n)解法及模板
2024-10-18 11:26:01
概率论中的组合数应该比较熟悉吧,在数论中组合数也具有重大意义,下面介绍组合数的解法:
方法一O(n^2):
利用公式(n,m)=(n-1,m-1)+(n-1,m):
模板:
#include<cstdio>
const int N = + ;
const int MOD = (int)1e9 + ;
int comb[N][N];//comb[n][m]就是C(n,m)
void init(){
for(int i = ; i < N; i ++){
comb[i][] = comb[i][i] = ;
for(int j = ; j < i; j ++){
comb[i][j] = comb[i-][j] + comb[i-][j-];
comb[i][j] %= MOD;
}
}
}
int main(){
init();
}
方法二(O(n)):
因为大部分题都有求余,所以我们大可利用逆元的原理(没求余的题目,其实你也可以把MOD自己开的大一点,这样一样可以用逆元做)。利用公式:
我们需要求阶乘和逆元阶乘。
模板:
const int MOD = (int)1e9 + ;
int F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘
void init(){
inv[] = ;
for(int i = ; i < N; i ++){
inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD;
}
F[] = Finv[] = ;
for(int i = ; i < N; i ++){
F[i] = F[i-] * 1ll * i % MOD;
Finv[i] = Finv[i-] * 1ll * inv[i] % MOD;
}
}
int comb(int n, int m){//comb(n, m)就是C(n, m)
if(m < || m > n) return ;
return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD;
}
int main(){
init();
}
最新文章
- ASM:《X86汇编语言-从实模式到保护模式》第17章:保护模式下中断和异常的处理与抢占式多任务
- Fragment中添加ListView而不使用ListFragment
- 优化MyBatis配置文件中的配置
- SQL 中怎么查询一个数据库中一共有多少个表
- 【jmeter】属性和变量
- C++组合问题
- JAVA:避免重复的创建对象
- Kendo Web UI Grid里时间格式转换
- Erlang虚拟机的启动
- Python Web框架篇:Django Model ORM(对象关系映射)
- MYSQL:数据库安装 windows
- C++顺序容器知识总结
- JAVA获取计算机CPU、硬盘、主板、网络等信息
- CodePad系列之-Tkinter窗体
- 记一次windows服务开发中遇到的问题
- CentOS下Crontab安装使用详细说明(转)
- Linux进程共享通信 -- mmap实现
- getIsDebuggable
- sql server 日志文件占用过多空间
- 提高你开发效率的十五个 Visual Studio 使用技巧