HDU-5226 Tom and matrix(组合数求模)
一、题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5226
二、题意
给一个大矩阵,其中,$a[i][j] = C_i^j$。输入5个参数,$x_1, y_1, x_2, y_2, p$,输出:以$x_1, y_1$为左上角,$x_2, y_2$为右下角的子矩阵中所有值累加和$\% p$的结果。
三、思路
看完题意后,想了一会儿,实在想不到如何降低复杂度。于是,就去看题解了。(PS:想了大概20分钟左右后还是没思路可以果断去看题解了。既然不知道方法,想再久也没用,最后还是要看题解的)。所以,我这篇文章,只是对知识点的整理和总结,而不是原创思路的分享。
对于组合数来说,有$C_n^m = C_{n-1}^{m-1} + C_{n-1}^m$。看个表。
这个表大家都很熟悉,就是组合数的表,因为$C_n^m = C_{n-1}^{m-1} + C_{n-1}^m$,所以,\[C_{n+1}^m = C_n^{m-1} + C_n^m = C_n^{m-1} + C_{n-1}^{m-1} + C_{n-1}^m = C_n^{m-1} + C_{n-1}^{m-1} + C_{n-2}^{m-1}+C_{n-2}^{m}\],由上述递推式可以发现,要计算$\sum\limits_{i=x_1}^{x_2}a[i][y]$,只要计算$C_{x_2+1}^{y+1} - C_{x_1}^{y+1}$即可。而且,更巧的是,对于对角线上的值,该式子也成立。
那么,有了上述推论,复杂度就降了一个维度了。从$y_1$枚举每一列到$y_2$,对每一列使用上述公式求值即可。
在做组合数求模$C_n^m\ \%\ p$的过程中,因为有可能存在$p \le \frac{n}{m}$的样例,那么就会出现这么一种情况:$p | n!, p | m!, p | (n-m)!$,如果使用n的阶乘*m的阶乘的逆元*(n-m)的阶乘的逆元来计算,返回值会是0。而实际上,真正的返回值并不一定是0。举个例子:
\[C_6^2 = \frac{6!}{2! * 4!} = \frac{720}{2 * 24} = 15\]
\[C_6^2\ \%\ 2 = 15\ \%\ 2 = 1 \ne 0 \]
所以,直接做计算组合数求模是不行的(也就是说,如果存在上述情况,用扩展欧几里得算法、费马小定理算法都不行了),要用lucas定理才行。
另外,还要注意的一点是,在初始化阶乘数组的时候,千万别忘了初始化阶乘逆元数组的第0个元素。即:inv[0] = 1。
四、源代码
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 100100 using namespace std; typedef long long LL; LL facts[MAXN], inv0[MAXN], x1, x2, y1, y2, p; LL qpow(LL a, LL x) { LL res = ; ) { )res = (res * a) % p; a = (a * a) % p; x >>= ; } return res; } void init() { facts[] = inv0[] = ; ; i < MAXN; ++i) { facts[i] = (facts[i - ] * i) % p; inv0[i] = qpow(facts[i], p - ); } } LL C(LL n, LL m) { ; ); )return n % p; return facts[n] * inv0[m] % p * inv0[n - m] % p; } LL lucas(LL n, LL m) { if(n < p && m < p)return C(n, m); else return lucas(n / p, m / p) * lucas(n % p, m % p) % p; } int main() { #ifndef ONLINE_JUDGE freopen("input.txt", "r", stdin); #endif while(~scanf("%I64d %I64d %I64d %I64d %I64d", &x1, &y1, &x2, &y2, &p)) { init(); LL ans = ; ;i <= y2 + ;++i)ans = (ans + lucas(x2 + , i) - lucas(x1, i) + p) % p; printf("%I64d\n", ans); } ; }
HDU-5226 Tom and matrix(组合数求模)的更多相关文章
- 组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix
Tom and matrix Problem's Link: http://acm.hdu.edu.cn/showproblem.php?pid=5226 Mean: 题意很简单,略. analy ...
- HDU 5226 Tom and matrix(组合数学+Lucas定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5226 题意:给一个矩阵a,a[i][j] = C(i,j)(i>=j) or 0(i < ...
- sdut2164Binomial Coeffcients(组合数求模)
http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2164 贴一篇写组合数求mod比较好的帖子 这里 ...
- HDU-3944 DP?(组合数求模)
一.题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3944 二.题意 给一个巨大的杨辉三角,采用类似DP入门题“数字三角形”的方式求从顶点$(0, 0) ...
- 【转载】【转自AekdyCoin的组合数取模】
本篇文章主要介绍了"[组合数求模] 转自AekdyCoin",主要涉及到[组合数求模] 转自AekdyCoin方面的内容,对于[组合数求模] 转自AekdyCoin感兴趣的同学可以 ...
- 【转】AC神组合数取模大全
貌似少了几张图片,不过没有图片也没什么关系的感觉. 最后的究极篇也想出来了,但是貌似找不到题目,好尴尬.. 这个表示的是从n个元素中选取m个元素的方案数. (PS.组合数求模似乎只用在信息学竞赛和 A ...
- 排列组合+组合数取模 HDU 5894
// 排列组合+组合数取模 HDU 5894 // 题意:n个座位不同,m个人去坐(人是一样的),每个人之间至少相隔k个座位问方案数 // 思路: // 定好m个人 相邻人之间k个座位 剩下就剩n-( ...
- hdu 3944 DP? 组合数取模(Lucas定理+预处理+帕斯卡公式优化)
DP? Problem Description Figure 1 shows the Yang Hui Triangle. We number the row from top to bottom 0 ...
- hdu 2065 "红色病毒"问题(快速幂求模)
n=1 --> ans = 2 = 1*2 = 2^0(2^0+1) n=2 --> ans = 6 = 2*3 = 2^1(2^1+1) n=3 --> ans = 20 ...
随机推荐
- hdu 4549 M斐波那契数列 矩阵快速幂+欧拉定理
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Problem ...
- Prototype(原型)
意图: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性: 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者为了避免创建一个与产品类层次平行的工厂类层次时:或者当一个 ...
- redis高可用 - redis集群
redis-sentinel方案提供了单点的高可用解决方案,但是当数据量和业务量极速增长时,单点的reids不可能无限的纵向扩容(增大内存),这个时候就需要redis有集群的能力来扛. redis集群 ...
- 将keras模型在django中应用时出现的小问题——ValueError: Tensor Tensor("dense_2/Softmax:0", shape=(?, 8), dtype=float32) is not an element of this graph.
本文原出处(感谢作者提供):https://zhuanlan.zhihu.com/p/27101000 将keras模型在django中应用时出现的小问题 王岳王院长 10 个月前 keras 一个做 ...
- hdu4280网络流之dinic
这题就是个模板题,不过我是第一次写dinic,好久没用链式前向星又不会了... 时间:9126ms #include<map> #include<set> #include&l ...
- VirtualBox使用物理硬盘建立磁盘
VirtualBox,只能用命令行来 建立磁盘才可以使用物理硬盘. 1.运行cmd,cd进入你的VirtualBox目录,如: cd C:\Program Files\Sun\VirtualBox ...
- BZOJ3288 Mato矩阵
网上说高斯消元得到下三角矩阵然后都是phi(i)...反着我是搞不出来 打个表什么的还是能看出来点奇怪的东西,比如后面能整除前面的,然后再乱搞吧2333 /********************** ...
- 前序+中序->后序 中序+后序->前序
前序+中序->后序 #include <bits/stdc++.h> using namespace std; struct node { char elem; node* l; n ...
- Xadmin的配置及使用
xadmin是Django的第三方扩展,可是使Django的admin站点使用更方便. 1. 安装 通过如下命令安装xadmin的最新版 pip install https://github.com/ ...
- L178 smart meter watchdog
There is "no realistic prospect" of the government meeting its own deadline to install sma ...