关于模运算

前言

写这篇文章的时候,本蒟蒻正在挑战3个月达省一;

之前一直对模运算耿耿于怀十分好奇,遂决定,今天拿下;

最后在正文开始之前放一个搞笑的东西:

关于模运算的定义

我们先定义带余除法 (其实就是除法):
\(设两个数 a,m \in \symbb{Z}, m \not= 0,则a、m的带余除法定义为:\)

存在唯一的整数q、r(r必须大于等于0),使得

\[a = qm+r \]

我们记a模m为: \(a \bmod m\)

我们把 \(q\) 称做商,\(r\) 称做余数(也称a模m的结果),记作:

\[r = a \bmod m \]

关于114514 & 998244353

OI 中,模运算最直接的用处就是解决一些需要处理带模运算的题目;

而 \(114514\) 和 \(998244353\) 这两个神奇的模数就不得不提一下了:

\(114514\) 请自行百度(主要是我也没查出来什么), \(998244353\) 有如下的几个特点:

1.它的二进制表达是:111011100000000000000000000001

2.它是一个质数。

3.它是一个奇数。

4.它可以表达为两个数的平方和:\(998244353 = 3943^2 + 31348^2\)

5.它是勾股数之一:\(998244353^2 = 247210328^2 + 967149855^2\)

6.它可以被表达为:\(998244353 = 7 \times 17 \times 2^{23} + 1\)

7.998244353最优美的性质莫过于它是个完美恶臭数:

\[998244353=( 114514 * ( 54-1+114 * (1+14*5+1+4) ) ) + ( 4+11451 * (4-1-15+14) ) + ( 11+41*54 + (141+541) ) + (4-1-15+14) \]

之所以称为完美,因为每一个括号里114514都出现了正整数次;

Tips :\(998244353\) 最大的一个特点是:出题人 \(99\%\) 的情况下是不会使用这个数的,取而代之的是 \(998234353\) 、\(998244553\) ,不过应该没人会栽在上面

模运算的两个等式

\[\S 1. (a+b) \bmod m = ((a \bmod m)+(b \bmod m)) \bmod m \]

\[\S 2. (a \times b) \bmod m = ((a \bmod m) \times (b \bmod m)) \bmod m \]

这两个是经常会用到的等式,大部分的OI题目都要求取模

但是通常情况下,这时的结果都远远超出了int型的范围,我们需要在运算过程中就直接取模,而这步的正确性就是依赖于上面的两个等式

下面我们来证明一下:

证明1:

依据带余除法,我们设 \(a = q_1m + r_1,\) \(b = q_2m + r_2\),那么带入等式左边,我们有:

\[(a+b)\bmod m = (q_1m+r_1+q_2m+r_2) \bmod m \]

更进一步,合并同类项:

\[原式 = ((q_1+q_2)m+r_1+r_2) \bmod m \]

引入一个定理:

\(a \bmod m\) 的结果与 \((a+k \times m) \bmod m\) 是一样的,通俗来说,就是一个数除以另一个数的余数,与这个数加上任意倍的除数之后除以除数的余数是一样的

显然,这里相当于有一个商为 \((q_1+q_2)\) ,余数为 \(r_1+r_2\) 的数模 \(m\) ,当然就等于直接对 \(r_1+r_2\) 模 \(m\) (不妨自己试一下,\(9 \bmod 2\) 和 \(1 \bmod 2\)一不一样)

所以我们有:

\[((q_1+q_2)m+r_1+r_2) \bmod m = (r_1+r_2) \bmod m \]

而 \(r_1,r_2\) 就是 \(a \bmod m\) ,\(b \bmod m\) ,带入得:

\[(r_1+r_2) \bmod m = ((a \bmod m)+(b \bmod m)) \bmod m \]

证毕

证明2:

仍然依据带余除法,我们设 \(a = q_1m + r_1,\) \(b = q_2m + r_2\),那么带入等式左边,我们有:

\[(a \times b)\bmod m = ((q_1m+r1) \times (q_2m + r_2)) \bmod m \]

展开:

\[= (q_1q_2m^2+(q_1r_2+q_2r_1)m+r_1r_2) \bmod m \]

这里括号内的前两项仍然是 \(m\) 的倍数,所以可以和1一样进行替换

\[= (r_1r_2) \bmod m \]

而 \(r_1\) 、\(r_2\) 分别是 \(a \bmod m\) ,\(b \bmod m\) ,带入得:

\[= ((a \bmod m) \times (b \bmod m)) \bmod m \]

证毕

同余

如果在计算过程中出现了负数,应该如何处理呢(也就是对负数取模,这里不能直接取,这样是负的)?

我们回归问题的本质:求出这个负数除以m的余数

也就是说,我们只要找到一个和这个负数除以m的余数一样的正数,就可以找到这个负数除以m的余数,而所谓的"和这个负数除以m的余数一样的正数",简称和这个负数同余(具有同样的余数)

当然,仅说同余是没有意义的,我们需要指定模数(除数),才是有意义的;

具体而言:假如有两个整数 \(x,y\) ,若 \((x-y) \bmod m = 0\) ,则称 \(x,y\) 在模 \(m\) 意义下同余(具有同样的余数)

为什么差是倍数就同余呢 ,仍然依据带余除法,我们设 \(x = q_1m + r_1,\) \(y = q_2m + r_2\),那么带入等式左边,我们有:

\[原式 = ((q_1-q_2)m+(r_1-r_2)) \bmod m \]

而因为这玩意为0,所以 \((q_1-q_2)m+(r_1-r_2)\) 必然是 \(m\) 的倍数,也就是能写成 \(n \times m\)的形式( \(n\) 是一个整数),显然,\(n = q_1-q_2\) ,所以 \(r_1 - r_2 = 0\),也就是说,\(r_1 = r_2\) ,即 \(x,y\) 同余;

现在给出定义:对于任意的两个数 \(x,y\) ,若有 \((x-y) \bmod m = 0\) ,那么我们称 \(x,y\) 在模 \(m\) 意义下同余,记为:

\[x \equiv y\pmod m \]

那么回到最初的问题:如何找到和这个负数同余的正数;

我们假设这个数是 \(-15\),根据同余的定义,我们有:\(-15 \equiv 5 \pmod{10}\) (\(-15-5 = -20 \bmod 10 = 0\) ,显然-20是10的-2倍)

那么怎样从 \(-15\) 推出 \(5\) 来呢?

我们使用 「模m加m」 的方法,即先模m得到一个负数,随后加上m,就得到了和m同余的正数:
\(-15 \bmod 10 = -5\),\(-5+10 = 5\),这样就得到了5,随后再对5模10即可(这里的负余数-5是大部分的编程语言的默认做法,但是不符合数学定义);

对于对一个不知正负的数字 \(x\) 取模,我们进行如下计算:
\(x \bmod m = (x \bmod m + m) \bmod m\)

最后

到这里这篇介绍模运算的文章就结束了(当然不包含对除法的取模,这个比较复杂,需要适当了解群论和乘法逆元),可能会有笔误,欢迎各位指正

相关推荐
ACEEE122212 分钟前
解读DeepSeek-V3.2-Exp:基于MLA架构的Lightning Index如何重塑长上下文效率
人工智能·深度学习·算法·架构·deep
qq_4378964319 分钟前
unsigned 是等于 unsigned int
开发语言·c++·算法·c
Learn Beyond Limits1 小时前
Using per-item Features|使用每项特征
人工智能·python·神经网络·算法·机器学习·ai·吴恩达
greentea_20131 小时前
Codeforces Round 863 A. Insert Digit (1811)
数据结构·算法
小南家的青蛙1 小时前
LeetCode第51题 - N 皇后
算法·leetcode·职场和发展
文火冰糖的硅基工坊1 小时前
[创业之路-682]:实即虚,虚即实。真正的技术壁垒,藏在光路之外、电路之下、代码之中。
人工智能·算法·系统架构·制造·创业·产业链
2401_841495642 小时前
【计算机视觉】霍夫变换检测
图像处理·人工智能·python·opencv·算法·计算机视觉·霍夫变换
半桶水专家2 小时前
C语言中的setitimer函数详解
c语言·开发语言·算法
FS_tar4 小时前
高斯消元矩阵
c++·算法·矩阵
小蝙蝠侠4 小时前
安德烈·卡帕西:深入探索像ChatGPT这样的大语言模型内容列表
人工智能·算法·机器学习