组合数学总结
数学是毒瘤
组合数学总结。
如果说数论是数学的基础,那么组合数学往后就是高阶了。这之后的数学不再像数论那么板子,而是变得需要更多的推理和组合了。知识很简单,难的是应用。
本来还有什么容斥原理,看不懂,于是没放
初始化
为了方便快速求排列组合,我们需提前预处理阶乘和阶乘的乘法逆元。
令
是 的阶乘 的乘法逆元,不是 的乘法逆元! 2024/3/17 upd.
注意:若
注意:若
void init() {
fac[0] = inv[0] = 1;
for (int i = 1; i < MAXN; i++) {
fac[i] = fac[i - 1] * i % MOD;
inv[i] = power(fac[i], MOD - 2, MOD);
}
}
一般情况下,数论题都有一个
排列数
排列数的计算公式如下:
inline int A(int n, int m, int p) {
if (n < m) return 0;
return fac[n] * inv[n - m] % p;
}
组合数
组合数的计算公式如下:
inline int C(int n, int m, int p) {
if (n < m) return 0;
return fac[n] * inv[m] % p * inv[n - m] % p;
}
排列数和组合数都只需
若需要即时求组合数,可以根据公式直接记忆化搜索:
int C(int n, int m) {
if (m == 0 || m == n) return 1;
if (cc[n][m] != 0) return cc[n][m];
return cc[n][m] = C(n - 1, m) + C(n - 1, m - 1);
}
组合数性质
相当于将选出的集合对全集取补集,故数值不变。(对称性)
由定义导出的递推式。
组合数的递推式(杨辉三角的公式表达)。我们可以利用这个式子,在
这是二项式定理的特殊情况。取
二项式定理的另一种特殊情况,可取
拆组合数的式子,在处理某些数据结构题时会用到。
这是
带权和的一个式子,通过对
与上式类似,可以通过对多项式函数求导证明。
通过组合分析一一考虑
通过定义可以证明。
Lucas 定理
当
易知,
int lucas(int n, int m, int p) {
if (m == 0) return 1;
return C(n % p, m % p, p) * lucas(n / p, m / p, p) % p;
}
二项式反演
二项式反演用于解决“某个物品恰好若干个”这类计数问题。
直接摆公式。证明需要用到前文提到的组合数定理。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效