【学习笔记】基础数论——同余

引入

什么是余数?

假设你有 \(10\) 块糖果,要分给 \(3\) 个小朋友,每个小朋友分到 \(3\) 块,还剩 \(1\) 块。剩下的 \(1\) 就是余数。
数学写法:
\(10 \div 3 = 3 \dots 1\)
\(10 = 3\times 3 + 1\)

什么是同余?

如果两个数除以同一个数后,得到的余数相同,我们就说它们同余
例如:
\(15\div 4 = 3 \dots 3\)
\(7\div 4 = 1 \dots 3\)
它们的余数都是 \(3\),所以 \(15\)\(7\) 在模 \(4\) 下是同余的。
符号写作 \(15\equiv 7 \pmod{4}\)

如何判断 & 寻找?

  1. 判断是否同余
    • \(17\)\(5\) 在模 \(6\) 下同余吗?
    • \(17\div 6 = 2\dots 5\), \(5\div 6 = 0\dots 5\),余数相同,所以 \(17\equiv 5\pmod {6}\),同余。
  2. 找同余数
    • 在模 \(5\) 下,哪些数和 \(12\) 同余?
    • \(12\div 5 = 2\dots 2\),所以所有形如 \(5k+2\) 的数都和 \(12\) 同余,例如 \(2,7,12,17,22\) 等数值。

正文

同余的定义

同余,由高斯在 \(19\) 世纪初提出这一概念。
同余的语言使得人们能用类似处理等式的方法来处理整除关系

定义
\(m\) 是正整数,若 \(a\)\(b\) 是整数,且 \(m|(a-b)\),则称 \(a\)\(b\)\(m\) 同余。
\(a\)\(b\)\(m\) 同余,则记作 \(a\equiv b \pmod {m}\)
\(m \nmid (a-b)\),则记作 \(a\not\equiv b \pmod {m}\),并称 \(a\)\(m\) 不同余于 \(b\)
整数 \(m\) 称作同余的模。

数学里,用 \(\mid\) 表示整除。\(a\mid b\) 表示 \(a\) 整除 \(b\),意味着 \(a\)\(b\) 的因子,\(b\)\(a\) 的倍数。

举例

  • \(9\mid (22-4) = 18\)
  • 所以有 \(22\equiv 4\pmod{9}\)
  • 类似的 \(3\equiv -6\pmod{9}\)\(200\equiv 2\pmod{9}\)
  • 此外,\(9\nmid (13-5) = 8\),所以 \(13\not\equiv 5\pmod{9}\)

同余在生活中随处可见。
钟表对于小时是模 \(12\) 或者 \(24\),对于分钟和秒是模 \(60\);日历对于星期是模 \(7\),对于月份是模 \(12\),等等。

定理 & 证明

定理:
\(a\)\(b\) 是整数,则 \(a\equiv b\pmod{m}\) 当且仅当存在整数 \(k\),使得 \(a = b+km\)

证明:
\(a\equiv b\pmod{m}\),则 \(m\mid (a-b)\)。这说明存在整数 \(k\),使得 \(km = a-b\),所以 \(a = b+km\)

重要性质

\(m\) 是正整数,模 \(m\) 的同余满足下面的性质:

  • 自反性。若 \(a\) 是整数,则 \(a\equiv a\pmod{m}\)
  • 对称性。若 \(a\)\(b\) 是整数,且 \(a\equiv b\pmod{m}\),则 \(b\equiv a\pmod{m}\)
  • 传递性。若 \(a,b,c\) 是整数,且 \(a\equiv b\pmod{m}\),\(b\equiv c\pmod{m}\),则 \(a\equiv c\pmod{m}\)

性质的证明

  • 自反性:因为 \(m\mid (a-a)\),所以 \(a\equiv a\pmod{m}\)
  • 对称性:若 \(a\equiv b\pmod {m}\), 则 \(m\mid (a-b)\),从而存在整数 \(k\),使得 \(km = a-b\)。这说明 \((-k)m = b-a\),即 \(m|(b-a)\),因此 \(b\equiv a\pmod{m}\)
  • 传递性:若 \(a\equiv b\pmod{m}\),且 \(b\equiv c\pmod{m}\),存在整数 \(k\)\(l\), \(km = a-b\)\(lm = b-c\),于是 \(a-c = (a-b)+(b-c) = km+lm = (k+l)m\), 有 \(a\equiv c\pmod{m}\)

同余例题

题面
给定字符串 \(s\),将 \(s\) 不断拼接,得到一个无限长的字符串 \(t\)。求 \(t\) 中的第 \(n\) 个字符。
\(1\leq n\leq 10^9\)\(1\leq |s|\leq 10000\)

解法
\(len=|s|\)\(t\) 中的第 \(n\) 位其实上可以映射到 \(s\) 中的第 \(n\%len\) 位,当然,如果 \(len \mid n\),则是最后一位。直接输出即可。

剩余系 & 同余类

由上述定理可见,整数的集合被分成 \(m\) 个不同的集合,这些集合称为模 \(m\) 剩余系(同余类),每个同余类中的任意两个整数都是模 \(m\) 同余的。

定义:一个模 \(m\) 完全剩余系是一个整数的集合,使得每个整数恰和此集合中的一个元素模 \(m\) 同余。

模运算中的定理 & 证明

\(a,b,c\)\(m\) 都是整数,\(m>0\)\(a \equiv b\pmod{m}\),则有:

  • \(a+c \equiv b+c\pmod{m}\)
  • \(a-c \equiv b-c\pmod{m}\)
  • \(ac \equiv bc\pmod{m}\)

上面的证明非常简单,在此不多说了。

\(a,b,c\)\(m\) 都是整数,\(m>0\)\(d = \gcd(c,m)\),且有 \(ac\equiv bc\pmod{m}\),则有 \(a\equiv b\pmod{\frac{m}{d}}\)

证明
\(ac\equiv bc\pmod{m}\),则存在整数 \(k\),有 \(km = c(a-b)\)。两边同时除以 \(d\),得到 \(\frac{c}{d} (a-b) = k(\frac{m}{d})\)
因为 \(gcd(\frac{m}{d},\frac{c}{d}) = 1\), 有 \(\frac{m}{d}\mid (a-b)\),所以有 \(a\equiv b\pmod{\frac{m}{d}}\),得证。

计算机中的模运算

同余式相减时,结果可能出现负数,需要将运算结果加到正值,才是正确的余数。

比如说,我们要计算 \(a-b\) 的值取模 \(m\) 后的结果。不过由于 \(a\)\(b\) 的原值过大,一开始就对 \(m\) 进行了取模。
正常来讲,我们直接计算 (a-b)%m 就速速结束了,毫不费脑。
但是这里会有一个严重的事情,由于我们的 \(a\)\(b\) 都是取了模的,即使一开始满足 \(a \ge b\),取模后也不一定。
我们举个反例,如果 \(a=8\)\(b=6\) 并且 \(m=4\) 的话,\(a \mod m = 8 \mod 4 = 0\)\(b \mod m = 6 \mod 4 = 2\)\(0 < 2\)。可以看到,上面所说确实属实。
那该如何解决这个问题呢?很容易就能发现,其实上只要将它们的差(可能是负数)加上一个 \(m\) 以后再取模,就没问题了。
因此,最终的代码为 (a-b+m)%m。是不是也很简单呢?

模运算中的幂运算

如果 \(a\equiv b \pmod{m}\),则有 \(a^n\equiv b^n\pmod{m}\)

证明

  1. 采用数学归纳法,已知 \(m \mid (a^{-1}-b^{-1})\)
  2. 如果 \(m\mid (a^i - b^i)\),根据同余式相乘,\(a^i \equiv b^i\pmod{m}\)\(a\equiv b\pmod{m}\),则 \(a^{i+1}\equiv b^{i+1}\pmod{m}\)
  3. 肯定能够一直推到 \(n\),得证。

模运算中的除法推论

推论
\(a,b,c\)\(m\) 都是整数,\(m>0\)\(\gcd(c,m)=1\),且有 \(ac \equiv bc \pmod{m}\),则 \(a \equiv b \pmod{m}\)

该推论使得我们可以在模 \(m\) 同余式中消去和 \(m\) 互质的数。

模运算中的定理 & 证明

定理
\(a,b,c,d\)\(m\) 是整数,\(m>0\)\(a\equiv b\pmod{m}\),\(c\equiv d\pmod{m}\),则:

  • \(a+c\equiv b+d\pmod{m}\)
  • \(a-c \equiv b-d \pmod{m}\)
  • \(ac = bd\pmod{m}\)

证明
因为 \(a\equiv b\pmod{m}\),且 \(c\equiv d\pmod{m}\),我们有\(m\mid (a-b)\)\(m\mid (c-d)\),因此,存在整数 \(k\)\(l\),使得 \(km = a-b\)\(lm = c-d\)

接下来我们一条一条证明:

    • \((a+c)-(b+d) = (a-b)+(c-d) = km+lm+(k+l)m\)
    • 因此 \(m\mid [(a+c)-(b+d)]\),得证 \(a+c\equiv b+d\pmod{m}\)
    • \((a-c)-(b-d) = (a-b)-(c-d) = km-lm = (k-l)m\)
    • 因此 \(m\mid [(a-c)-(b-d)]\),得证 \(a-c \equiv b-d \pmod{m}\)
    • \(ac - bd = ac-bc+bc-bd = c(a-b) + b(c-d)= ckm + blm = m(ck+bl)\)
    • 因此 \(m\mid (ac-bd)\),得证 \(ac = bd\pmod{m}\)

计算机中的常见取余数计算

不少题目中,需要将最终结果取模后输出(常见如 \(998244353\)\(10^9+7\))。
如果计算操作只涉及加、减、乘运算,那么可以在中途计算时就取模。取模后的数与原数是同余的,不影响最后的取模结果。
如涉及除法,需要用到费马小定理,使用乘法逆元求解,详见此处

线性同余方程

\(x\) 是某未知整数,形如 \(ax\equiv b\pmod{m}\) 的同余式称为一元线性同余方程,其中 \(a,b\) 以及 \(m\) 均为已知数。

首先注意到,若 \(x = x_0\) 是同余方程的一个解,且 \(x_1 \equiv x_0\pmod{m}\),则 \(ax_1 \equiv ax_0\pmod{m}\),所以 \(x_1\) 也是一个解。因此,若一个模 \(m\) 同余类的某个元素是解,则此同余类的所有元素都是解.

拓展:一元线性同余方程 \(ax\equiv b\pmod{m}\) 等价于二元不定方程 \(ax-my = b\)

二元不定方程

现在要求求解二元不定方程 \(ax+by = c\)

第一步,我们要知道如何判定它是否有解。
首先考虑一些较弱的结论,容易发现,无论 \(x,y\) 的取值,左式一定是 \(d = \gcd(a,b)\) 的倍数,因此当 \(d\nmid c\) 时,方程显然无解。这使得我们可以为方程两侧同时除以 \(d\).
同时我们注意到同时除以 \(d\) 之后,\(a,b\) 互质,这说明我们可以将问题简化为求解 \(a,b\) 互质时的情形。
对于 \(a\perp b\),可以证明 \(ax \mod b\) 可以取到 \(0 \sim b-1\) 中的任意一个数。
所以若 \(d \mid c\),方程就一定有解.

接下来思考如何求解。

考虑 \(ax,by\) 满足 \(0 \le x\),\(y < b\)\(x \not= y\),则 \(ax\neq ay\pmod{b}\)。若存在则有 \(a(x-y) = 0\mod{b}\)
因为 \((a,b) = 1\)\(a\) 不含有任何 \(b\) 含有的质因子,对同余式的成立没有任何贡献,所以 \(x-y = 0\pmod{b}\),与限制矛盾。所以一定可以取遍 \(0 \sim b-1\).

裴(péi)蜀(shǔ)定理

\(a,b\) 是整数,且 \(\gcd(a,b) = d\),则对于任意的整数 \(x,y\)\(ax+by\) 一定都是 \(d\) 的倍数。

特别的,一定存在数 \(x\),\(y\),使得 \(ax+by = d\) 成立。

重要推论\(a,b\) 互质的充分必要条件是存在数 \(x,y\),使得 \(ax+by = 1\)

二元线性不定方程

我们现在要求解二元线性不定方程,其形如 \(ax+by = c\)

\(d = \gcd(a,b)\),则需要求解 \(ax+by = d\),并将其解乘以 \(\frac{c}{d}\) 即可。
根据上文中提到的裴蜀定理,方程的解必然存在。
注意到等式右端等于 \(x,y\) 前系数的最大公约数。回顾欧几里得算法,我们用到了关键结论 \(\gcd(a,b) = gcd(b,a\%b)\),将问题缩小到更小的规模上。利用这一思想,我们尝试将求解的方程也缩至更小的规模上。
假设我们已经得到了 \(bx' + (a\mod b)y' = d\) 的一组解,则 \(ax+by = bx'+(a\mod b)y' = bx' +(a-b\times \lfloor\frac{a}{b}\rfloor)y' = ay'+b(x'-\lfloor\frac{a}{b}\rfloor y')\)
对比等式两端,有 \(x = y'\)\(y = x' - \lfloor\frac{a}{b}\rfloor y'\)
不断递归计算即可。
递归边界即 \(b = 0\)时,根据辗转相除法,\(a = d\)
此时 \(x = 1\)\(y = 0\) 即为一组解。

扩展欧几里得算法

代码如下,非常简短:

void exgcd(int a,int b,int &x,int &y) {
    if(!b){x=1,y=0;return;}
    exgcd(b,a%b,y,x);y-=a/b*x;return;
}

二元线性不定方程

\(a,b\) 是整数且 \(d = \gcd(a,b)\),若 \(x = x_0\)\(y = y_0\)\(ax+by = c\) 的一个特解,那么所有的解均可表示为:

  • \(x = x_0+\frac{bn}{d}\)
  • \(y = y_0+\frac{an}{d}\)
    注:其中 \(n\) 是整数。
posted @ 2025-04-08 18:30  嘎嘎喵  阅读(198)  评论(2)    收藏  举报