博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
P3807 【模板】卢卡斯定理
阅读量:7230 次
发布时间:2019-06-29

本文共 1286 字,大约阅读时间需要 4 分钟。

刷数论模板啦。。。

在正事之前发现了一个小知识:组合数有两种书写方式。一种是形如\(C_3^2\),另一种是形如\(\binom{3}{2}\)。这两者等价。

卢卡斯定理其实也简单的:

\[\binom{m}{n}=\binom{m \mod p}{n \mod p} \times \binom{\lfloor \frac{m}{p} \rfloor }{ \lfloor \frac{n}{p} \rfloor} \mod p\]

这是一种简单的表达式。

lucas定理可以求大\(n,m\)的组合数取模。

这是一种递归的算法。下取整的大部分我们可以再次递归缩小范围求解,而取模的部分我们直接暴力来做。

如何暴力?

组合数的定义式:

\[C_m^n=\frac{m!}{n!(m-n)!}\]

在模意义下我们就没除法了。所以我们就要用到乘法逆元了。

我们先预处理出这些阶乘,然后可以用任意一种方法来求这两个阶乘的逆元。暴力乘上去即可。

代码:

#include
const int maxn = 1000005;#define ll long longll n, m, p;ll frac[maxn];ll pow_mod(ll x, ll y, ll p){ ll ans = 1, base = x % p; while(y) { if(y & 1) ans = ans * base % p; base = base * base % p; y >>= 1; } return ans % p;}ll inv(ll x, ll p){ return pow_mod(x, p - 2, p) % p;}ll C(ll x, ll y, ll p){ if(x < y) return 0; return frac[x] * inv(frac[y], p) % p * inv(frac[x - y], p) % p;}ll lucas(ll x, ll y, ll p){ if(y == 0) return 1; return C(x % p, y % p, p) * lucas(x / p, y / p, p) % p;}int main(){ int T; scanf("%d", &T); while(T--) { scanf("%lld%lld%lld", &n, &m, &p); frac[0] = 1; for(int i = 1; i <= p; i++) frac[i] = frac[i - 1] * i % p; printf("%lld\n", lucas(n + m, n, p)); } return 0;}

转载于:https://www.cnblogs.com/Garen-Wang/p/9745873.html

你可能感兴趣的文章
文件系统存储数据,与数据库系统存储数据的差别
查看>>
linux之awk
查看>>
第九章 接口
查看>>
XCode4.2.1 使用NavigationController实现View切换
查看>>
如何让NSURLConnection在子线程中运行
查看>>
es6-Generator
查看>>
Python3.6单例模式报错TypeError: object() takes no parameters的解决方法
查看>>
HTML常用标记(选择性,不全)
查看>>
用一辈子去领悟的22条生活真谛
查看>>
1968: [Ahoi2005]COMMON 约数研究
查看>>
discuz 启用html code 显示问题
查看>>
A1027. Colors in Mars (20)
查看>>
[SRM568]DisjointSemicircles
查看>>
9个很有发展潜力的PHP开源项目
查看>>
python中pymysql数据编码的问题
查看>>
HDFS基本原理及数据存取实战
查看>>
j2ee页面静态化方案encache web cache框架详解1
查看>>
php高级注入
查看>>
[硬件]三维点云数据获取
查看>>
nagios安装配置
查看>>