信息学竞赛中计算结果对 109+7 取余数的原因

大家在学习信息学竞赛的过程中,总是会遇到要求计算结果对 109+7 或者 10007 这样的数取余数的结果,比如:http://codeforces.com/problemset/problem/1423/J

链接中的题目中就有一句话:

For each test case i, print the answer on separate lines: number of polynomials P as described in statement such that P(2)=mi, modulo 109+7.

那么为什么要对 109+7 呢?

最主要的原因是一些运算的结果会很大,如果不在计算的过程中模 109+7(或者别的一些数),答案可能会超过 long long 的表示范围。而如果两个数 a,b 满足 0a,b<109+7,则对其进行加、减、乘、除(整除或取余)操作,都不会让结果超过 long long 的表示范围(当然,除法运算会复杂一点,不能简单地除,除以 a 需要转变为乘以 a 的逆,这部分不作为这篇随笔的讨论范围),然后计算的结果再对 109+7 取余,又能保证结果小于 109+7 了。

同时,对于算术运算,我们能够证明在计算过程中不停地模一个数,和计算完了之后再模这个数的结果是一样的。这部分相信学过 同余 的同学应该也都能够理解。

所以最主要的目的就是:让我们的计算过程用 long long 就可以解决。

那么为什么一般都选择 109+7 或者 10007 这样的数呢?

我们会发现一般取余的数都是 素数 ,这也是有原因的。

假设我要输出的是答案模 m 的结果(即答案除以 m 的余数)。假设 m 是有一个有较多约数的数,同时在数据中存在 q 满足 gcd(m,q)=d>1 (即假设有一个数 q ,它和 m 的最大公约数是一个大于 1 的数 d),即存在 —— m=a×d,q=b×d,则有以下等式:

q%m=qm×[q/m]=qm×[b/a]

(这里 [x] 表示 x 向下取整的结果)其中 b/a 的结果是 [0,b] 范围内的正整数,也就是说,[b/a] 的结果只有 b+1 种可能,而 m 是一个预先确定的数。因此,上式的值就只有 b+1 种可能了。这样,虽然模运算之后的余数仍然在 [0,m1] 范围内,但是它的取值仅限于等式可能取到的那些值,也就是说余数的分布变得不均匀了。所以,m 的约数越多,发生这种余数不均匀的情况就越频繁,冲突的几率就越高。而素数的约数是最少的,因此一般选 m 为小于某个区域长度的最大素数。于是 109+7 就变成一个很合适的选择方案,一方面能保证记起来比较方便,另一方面也能保证模 109+7 的结果不会超出 long long 表示范围。

posted @   quanjun  阅读(1652)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
历史上的今天:
2020-02-24 洛谷P1991 无线通讯网 题解 并查集+二分答案
点击右上角即可分享
微信分享提示