为什么对1e9+7取模

本篇是基于两篇较清晰的解析:为什么是1e9+71e9+7取模的易错点的总结

为什么是1e9+7?

1、1e9+7对int来说非常大,通常1e9代表无穷大

int数值的范围是-2147483648 到 2147483647,1e10已经超出范围了,所以在计算最小值的操作中,1e9常用来初始化代表无穷大。

2、对1e9+7取模的原因

在一些算法题目中,会遇到这样的情况:
由于结果可能较大,将结果mod 1e9+7,即mod 1000000007 。
或者

( a * b ) % c = [ ( a % c ) * ( b % c ) ] % c

而这个c最常见的还是1e9+7。
有时候结果比较大的时候,会对结果进行mod 1e9+7操作。为什么呢?
第一:
1e9+7是一个很大的数,int32位的最大值为2147483647,所以对于int32位来说1000000007足够大。int64位的最大值为2^63-1,对于1000000007来说它的平方不会在int64中溢出所以在大数相乘的时候,因为(a∗b)%c=((a%c)∗(b%c))%c,所以相乘时两边都对1000000007取模,再保存在int64里面不会溢出 ,否则两个非常大的数在ab阶段就溢出了。有点于归一化的意思。
当一个问题只对答案的正确性有要求,而不在乎答案的数值,可能会需要将取值很大的数通过求余变小。
第二:
其次,1e9+7是一个质数,在模素数p的情况下a
n(a非p的倍数)的循环节长为p,这是减少冲突的一个原因。另一方面模素数p的环是无零因子环,也就是说两个非p倍数的数相乘再模p不会是零(如果是0的话,在多个数连乘的情况下会大大增加冲突概率)。比如说如果所有的结果都是偶数…你模6就只可能出现0, 2, 4这三种情况…但模5还是可以出现2, 4, 1, 3这四(4=5-1)种情况的… hash表如果是用取模的方法也要模一个大质数来减少冲突,出题人也会这样来 希望减少你“蒙对“的概率。

易错总结

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

2、(a∗b)%c 应该变化为((a%c)∗(b%c))%c,c一般为1e9+7

如果a和b都是非常大的数的话(a∗b)%c 操作还没轮到对c取模就爆了

3、取模加括号

(1)、注意顺序
下面的式子取模过程有个坑点:

res = res % mod + pre[i][j] % mod * a[i][j] % mod;

这行式子里面 * 和 % 是从左到右计算的,所以其实pre[i][j]取模后先与a[i][j]相乘了,a[i][j]并没有取模
应该为:

res = res % mod + pre[i][j] % mod * (a[i][j] % mod);

(2)、注意为(1e9+7)
1e9+7记得加括号

  • 18
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值