【C++ 取模mod易错点】由于答案可能会很大,请你将结果对1e9+7取模后再返回
在做算法题时我们经常会遇到这样一句话:
由于答案可能会很大,请你将结果对10^9 + 7取模后再返回
附:为什么很多程序竞赛题目都要求答案对 1e9+7 取模?
- 1000000007是一个质数
- int32位的最大值为2147483647,所以对于int32位来说1000000007足够大
- int64位的最大值为2^63-1,对于1000000007来说它的平方不会在int64中溢出 所以在大数相乘的时候,因为(a∗b)%c=((a%c)∗(b%c))%c,所以相乘时两边都对1000000007取模,再保存在int64里面不会溢出
这句话看上去只要对变量取模就可以了,但实际上取模的时机有一定的讲究,比如新手很容易犯一下两个错误
错误1:用max比较很大数据时,先取模
取mod的时候,如果题目要求你算最大值,并且说由于答案可能很大,输出结果请对1e9+7取,那你千万不能在max函数更新最大值时就取模,这样很可能会出错
比如:题目过程中有四个数据
2e9+7,1e9+6,1e9+5,1e9+4
然后算法中你用max求最大值时,如果先模上1e9+7,那你会得到1e9,1e9+6,1e9+5,1e9+4
,并且max函数算出的最大值是1e9+6,可是这四个数的最大值应该是2e9 + 7
才对
正确做法:在求max的时候不要先取mod,而是都以long long型数据比大小,最后得到最大值是2e9 + 7
,再对它取mod,得到结果是1e9 + 7
例题:1339. 分裂二叉树的最大乘积
错误代码示例
class Solution {public:// 乘积 = 某个节点下所有子节点的和 *(整个树的和 - 某个节点下所有子节点的和)typedef long long LL;LL rmax = 0;LL Total = 0;static const LL mod = 1e9 + 7;// 遍历每个结点,更新最大值LL TreeSum(TreeNode* root) {if (!root) return 0;LL left = TreeSum(root->left);LL right = TreeSum(root->right);LL subsum = left + right + root->val;// 此处先取模,所以数据很大时会出错rmax = max(rmax, (Total - subsum) * subsum % mod);return subsum;}int maxProduct(TreeNode* root) {if (!root) return 0;Total = TreeSum(root);rmax = 0;TreeSum(root);return rmax % mod;}
};
类似题:5752. 子数组最小乘积的最大值
错误2:直到return时才取模
如果让你算1+2+…+n的值(由于答案可能很大,输出结果请对1e9+7取)
n的取值范围是1 ~ 101000010^{10000}1010000
那显然如果你在中间过程中不先取mod,必然会爆数据范围,因为不管是int还是long long甚至是double(最大约1030810^{308}10308)都无法存下这个数据
...
long long res = 0;
for(int i = 1; i <= n ; i ++) {res = res + i; // n巨大,res无法存下这个数据
}return res % (1e9 + 7);
正确做法:在算res的过程中取模
...
long long res = 0;
for(int i = 1; i <= n ; i ++) {res = (res + i) % (1e9 + 7); // n巨大,res无法存下这个数据
}
return res;
有的人会说这不是与错误1矛盾了吗,其实完全不矛盾
- 错误1是在比较
多个
很大的数据(不超过long long) - 错误2是在维护
1个
很大的数据,那你先取模和后取模,就没有区别了,因为结果都是一样的
另外有的时候我们经常喜欢用 +=
之类的符号,但容易犯以下错误
long long res = 0;
for(int i = 1; i <= n ; i ++) {res += i % (1e9 + 7); // n巨大,res无法存下这个数据
}
return res;
上面的代码实际上并没有对res进行取模,而只是对iii进行取模,当res累加很多数后,是会超过long long,从而出现报错的。所以你要么在下面加一行res %= (1e9 + 7)
,要么用res = (res + i) % (1e9 + 7);
现在看面试题:剪绳子II这个题,就知道为什么不能用动态规划了,因为取余之后max函数就不能用来比大小
数据较小时下面代码是可以过的,数据大了就不行了,因为不能在max出取模
class Solution {public:// f(n) = max(f(i) * f(n - i)) i:1,..,n-1int cutRope(int number) {// number = 1,2,3时剪一刀,值会变小,所以特殊考虑这几种情况if(number < 2) return 0;if (number == 2) return 1;if (number == 3) return 2;int *f = new int[number + 1];f[1] = 1;f[2] = 2;f[3] = 3;// f(n) n大于3时,表示切若干刀后的最大值for (int i = 4; i <= number; i ++) {int rmax = number;for (int j = 1; j <= i / 2; j ++) {rmax = max(rmax, f[j] * f[i - j]);}f[i] = rmax;}int res = f[number];delete[] f;return res;}
};
错误3:是否真的取模了?
下面的式子取模过程有个坑点:
a[i][j]a[i][j]a[i][j]并没有取模就直接与pre[i][j]pre[i][j]pre[i][j]相乘了(*
和%
是从左往右算的)
res = res % mod + pre[i][j] % mod * a[i][j] % mod;
正确的写法:
res = res % mod + pre[i][j] % mod * (a[i][j] % mod);
写在最后
✨原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}原创不易,还希望各位大佬支持一下
【C++ 取模mod易错点】由于答案可能会很大,请你将结果对1e9+7取模后再返回相关推荐
- 2022年二级注册建筑师《场地设计》考试易错题及答案
题库来源:优题宝公众号 2022年二级注册建筑师<场地设计>考试易错题及答案,根据最新二级注册建筑师大纲与历年真题汇总编写,包含二级注册建筑师常考重点题型与知识点,有助于考生复习备考二级注 ...
- 京东商城百万数据抓取--苏宁易购,淘宝网,京东商城,百万级价格数据海量抓取
按照惯例先上成果: 过了分割线就是代码 ps:2020.5.14更新了代码:京东商城每周都会更改规则咱们也不能落后 # -*- coding: utf-8 -*- import requests im ...
- 求2的n次方对1e9+7的模,n大约为10的100000次方(费马小定理)
昨天做了一个题,简化题意后就是求2的n次方对1e9+7的模,其中1<=n<=10100000.这个就算用快速幂加大数也会超时,查了之后才知道这类题是对费马小定理的考察. 费马小定理:假如p ...
- 为什么对1e9+7取模
本篇是基于两篇较清晰的解析:为什么是1e9+7和1e9+7取模的易错点的总结 为什么是1e9+7? 1.1e9+7对int来说非常大,通常1e9代表无穷大 int数值的范围是-2147483648 到 ...
- # 汇编期末考试复习【选择易错题】
汇编期末考试复习[选择易错题] (来自南大科院周权来题库--战无不胜的毛泽东思想) 1.用汇编语言编写的程序称为 ( ) A. 汇编程序 B. 源程序 C.可执行文件 D.目标程序 答案:B 注意区分 ...
- 爬取三千条数据需要多久_只需几十行代码,Python就能轻松爬取 3000+ 上市公司的信息...
点击关注"Python学习与数据挖掘" 更多超级干货第一时间推送给你哦!!! 入门爬虫很容易,几行代码就可以,可以说是学习 Python 最简单的途径.刚开始动手写爬虫,你只需要关 ...
- C语言下取整下半个方括号,c语言易错知识点总结[工作范文](28页)-原创力文档...
c语言易错知识点总结 篇一:c语言易错知识 C语言教学中学生容易出错的知识点解析 0引言 C语言是一种很灵活的语言,在程序调试过程中常常会 遇到一些难解决的问题,一般语法错误计算机能检测出来, 而逻辑 ...
- Java 取余 (remain),取模 (mod) 的 区别和运算
范围区别:取模主要是用于计算机术语中.取余则更多是数学概念. 主要的区别在于对负整数进行除法运算时操作不同 那么具体是怎样的不同? 首先需要知道Java中如何取模: Java中用符号%对数字进行取模, ...
- matlab 取余(rem)和取模(mod)的区别
取余(rem)和取模(mod)的区别 Matlab 生成机制 取余:采取fix()函数,向0方向取整 取模:采取floor()函数,向无穷小方向取整 当A,B异号时(其实同号也是这个规律) 取余:结果 ...
最新文章
- c语言如何输出整串链表,大神帮我看一下怎么输入输出一个链表,我输入了但是没输出啊...
- 在RHEL-4下半小时搭建Sendmail邮件服务器(下)
- 相关子查询 与非相关子查询
- JMeter性能测试入门
- Django(part6)--利用正则的组名进行关键字传参
- scala语言示例_var关键字与Scala中的示例
- relu函数_ECCV 2020,在视觉任务上大幅超越ReLU的新型激活函数
- 深入理解 GraphQL
- ArcGis中计算栅格数据指定区域的面积
- 【java_wxid项目】【第十五章】【Spring Cloud Skywalking集成】
- 计算机专业提升计划范文,民航个人提升计划范文个人职业规划方案.doc
- 关于深恶痛绝的file类的delete问题
- 华大单片机HC32L130/HC32L136PWM配置
- www.ty66.php,韬轩阁
- Qt官方示例-虚拟键盘使用
- 第六章 Cesium学习入门之添加Geojson数据(dataSource)
- Ubuntu下非常给力的下载工具--uget+aria2
- mysql.proc is wrong_解决警告:数据库错误Column count of mysql.proc is wrong.
- 二进制八进制十进制十六进制及原码反码补码
- iOS 利用余弦函数实现卡片浏览工具
热门文章
- 处理C++源代码的程序
- 城轨车辆段联锁设备采用计算机联锁,车辆段计算机联锁系统简介
- HDU3001 Traveling (状压dp+三进制+Tsp问题总结)
- IDEA中的Structure模块使用详解
- 地震仪器专题-测震仪器发展简史
- Incorrect credentials. Request response: 401 Unauthorized
- 好的github源码记录(包括人脸...)
- Inside LightWave v9
- Tire town school learn
- GO:交互式命令行工具 survey