同余&逆元&CRT

· · 个人记录

同余&逆元&CRT

前记

upd 2022/10/9 14:36:06 : 修改了一些错误。

upd 2023/4/14 17:50:12 :修改了 CRT 部分并增加了 EXCRT。

第一篇学习笔记

之前搞了好几天,后来发现忘得差不多了,又重新温习,顺便做个笔记;涉及众多式子,如果有错请指出

目录:
1.同余式
2.裴蜀定理
3.欧几里得&扩展欧几里得
4.(乘法)逆元
5.求(乘法)逆元
6.CRT&EXCRT

1.同余式

如果两个数 ab 除以 m 后的余数相同,我们称 ab 对模 m 同余,记作

a \equiv b \pmod m

同余式就是如上这个式子,如果换成比较简单的形式就是

a = b + km\ \ (k \in \mathbb Z)

同时他还有个基本性质

显然的,若 a \equiv b \pmod m,当且仅当 m \mid (a-b),换言之若 a \not\equiv b \pmod m,则 m \nmid (a-b)

这里 a \mid b 表示 a 整除 b ,即 b 能被 a 整除

同余关系还具有

自反性:a \equiv a \pmod m

对称性:a \equiv b \pmod m,则 b \equiv a \pmod m

传递性:a \equiv b \pmod m,且 b \equiv c \pmod m,则 a \equiv c \pmod m

这些性质都可以根据变形后的式子轻易得出。

2.裴蜀定理

2.1裴蜀定理

在了解了同余式的定义后,我们来看一个与之相关的定理

裴蜀定理得名于法国数学家艾蒂安·裴蜀,亦称贝祖定理。

1.裴蜀定理是指方程 ax + by = m 有解,当且仅当 m\gcd(a,b) 的倍数时,方程有整数解

2.同时,一定存在整数 x,y,使 ax+by=\gcd(a,b) 成立;

3.特别的,只有 ab 互质时,ax + by = 1 才有整数解。

极不严谨的证明:

ax + by = m

方程两边同时除以 \gcd (a,b)

\dfrac{ax}{\gcd(a,b)} + \dfrac{by}{\gcd(a,b)} = \dfrac{m}{\gcd(a,b)}

因为 \gcd(a,b) \mid a \gcd(a,b) \mid b,所以 \gcd(a,b) \mid ax \gcd(a,b) \mid by,则 \gcd(a,b) \mid m

通俗来说就是方程左边一定为整数,所以方程右边也一定为整数,所以 m 一定是 \gcd(a,b) 的倍数

更严谨的证明方法请 bdfs。

2.2 同余式与裴蜀定理的关系

那么为什么说同余式与裴蜀定理有关呢,因为

ax \equiv m \pmod b ax = by + m ax - by = m

由于我们要求的方程是与 x 有关的方程, y 只是辅助答案且取值为任意整数,所以我们可以写成

ax + by = m

对于这个方程我们便可用扩展欧几里得来求解

3.欧几里得&扩展欧几里得

3.1 欧几里得算法

我们自然是要先来看看欧几里得算法的

古希腊数学家欧几里得在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里得算法。

欧几里得算法又称辗转相除法,一般用来求两个数的最大公约数,即

\gcd(a,b) = \gcd(b,a\%b)

证明:

假设 a>b

r=a\%b,d=\gcd(a,b)

a 可以表示成 kb+r ( k 为正整数)

r 就等于 a-kb

我们知道 d\mid a,d\mid b,则 d\mid r

因此 d 也是 ba\%b 的最大公因数

int gcd(int a,int b){return (b)?gcd(b,a%b):a;}
#include<algorithm>
using namespace std;
int a,b;
int main(){int c=__gcd(a,b);}

3.2 扩展欧几里得

扩展欧几里得算法是欧几里得算法的扩展(废话),即我们在辗转相除的过程中,求出 ax + by =\gcd(a,b) 的一组特解,设 \gcd(a,b)d

具体的来说我们在进行辗转相除时

设当前的两个数为 a,b(这里不是给出的 a,b,而是辗转相除过程中的 a,b

则下一轮要递归时的两个数为 b,a\%b

假设我们已经求出了 bx_0+(a\%b)y_0 = d,我们现在就是要利用已得出的 x_0,y_0 来推导出 ax+by=d

因为 a\%b = a - b \lfloor a/b \rfloor,则前式可以变为

bx_0+( a - b \lfloor a/b \rfloor )y_0 = d

整理得

ay_0 + b (x_0-\lfloor a/b \rfloor y_0) = d

所以

\begin{cases} x=y_0 \\ y=x_0-\lfloor a/b \rfloor y_0 \end{cases}

那么我们的边界条件呢?

我们在辗转相除时最后当 b=0 时,我们返回的是 a,即 d

也就是说相当于 a+0=d

所以初始时 x=1,y=0,(其实 y 可以为任何数)

设求出来的特解为 x,y,通解即为

\begin{cases}x_k = x+k \dfrac{b}{gcd(a,b)} \\ y_k=y-k \dfrac{a}{gcd(a,b)} \end{cases}

另外,扩展欧几里得还可以用来求逆元

//用来求不定方程 ax+by=c 的解
int x,y;
int exgcd(int a,int b,int &x,int &y)
{
    if(!b){x=1,y=0;return a;}
    int d=exgcd(b,a%b,y,x);
    y-=(a/b)*x;return d;
}
例题:
P1082 [NOIP2012 提高组] 同余方程
P1516 青蛙的约会

4.逆元

在数论中,如果 ab \equiv 1 \pmod p ,我们就说 ab 在模 p 意义下互为乘法逆元,记作 a=inv(b)

实际意义即如果要在模 p 意义下除以一个数,就相当于上这个数在模 p 意义下的逆元

通常使用扩展欧几里得,费马小定理,和线性递推法来求乘法逆元

5.求逆元

5.1 扩展欧几里得法

我们设 ba 在模 p 意义下的逆元,则

ab \equiv 1 \pmod p

就相当于求

ab+pk=1

利用扩展欧几里得法求解即可

//用来求a在%p意义下的乘法逆元x
int x,y,a,p;
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 ;
}
int main()
{
  exgcd(a,p,x,y);
  x=(x%p+p)%p;
}

5.2 费马小定理

皮埃尔·德·费马于1636年发现了这个定理。在一封1640年10月18日的信中他第一次使用了上面的书写方式。在他的信中费马还提出a是一个素数的要求,但是这个要求实际上是不必要的。

费马小定理为:若 p 是质数,且 \gcd(a,p) = 1,则有

a^{p-1} \equiv 1 \pmod p

至于证明,我不会

费马小定理的证明

从逆元的定义推导,可得 a \cdot inv(a) \equiv 1 \equiv a^{p-1} \pmod p,于是有

inv(a) \equiv a^{p-2} \pmod p

利用快速幂计算 a^{p-2} 即可

//仅适用于p为质数
int a,b,p,ans=1;
int main()
{
    b=p-2;
    while(b)
    {
        if(b&1) ans=ans*a%p;
        a=a*a%p;
        b>>=1;
    }
}

5.3 线性递推法

同时求逆元还用一种线性递推法

inv(a) = - \lfloor p/a \rfloor \cdot inv(p\ mod\ a) \pmod p

证明:

p=aq+r ,即 q= \lfloor p/a \rfloor,r=p \% a

在模 p 意义下,有 aq+r \equiv 0 \pmod p

整理得 a=-r \cdot inv(q) \pmod p

inv(a)=-q \cdot inv(r) \pmod p

inv(a) = - \lfloor p/a \rfloor \cdot inv(p\ mod\ a) \pmod p

//仅适用于p是质数
ans[1]=1;
for(int i=2;i<=n;i++)
{
    ans[i]=(-p/i*ans[p%i]);
    ans[i]=(ans[i]%p+p)%p;
}
例题
P3811 【模板】乘法逆元

6.CRT & EXCRT

孙子定理是中国古代求解一次同余式组的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题。

给定 n 组非负整数 a_i, b_i,求解关于 x 的方程组的最小非负整数解。

\begin{cases} x \equiv b_1\ ({\rm mod}\ a_1) \\ x\equiv b_2\ ({\rm mod}\ a_2) \\ ... \\ x \equiv b_n\ ({\rm mod}\ a_n)\end{cases}

6.1 中国剩余定理(CRT)

中国剩余定理有一个前提是模数 b_i 两两互质

如果我们将每个方程分开看:

\begin{cases} x_1 \equiv b_1 \pmod {a_1} \\ x_2 \equiv b_2 \pmod {a_2} \\ x_3 \equiv b_3 \pmod {a_3} \\ \cdots \end{cases}

如果已经满足了 x_1 \equiv b_1 \pmod {a_1} ,那么只有当 a_1 \mid x_2 时,x_1+x_2 \equiv b_1 \pmod {a_1}

同理当 a_1 \mid x_2,a_1 \mid x_3 时, x_1+x_2+x_3 \equiv b_1 \pmod {a_1}

所以设 p=\prod\limits_{i=1}^n a_i,r_i=\prod\limits_{j=1,j\not=i}^{n} a_j=\dfrac{p}{a_i},m_i=\dfrac{x_i}{r_i},我们要求得一个解 x=\sum\limits_{i=1}^{n} a_i,只需要解出:

\begin{cases} r_1 \cdot m_1 \equiv b_1 \pmod {a_1} \\ r_2 \cdot m_2 \equiv b_2 \pmod {a_2} \\ r_3 \cdot m_3 \equiv b_3 \pmod {a_3} \\ \cdots \end{cases}

由于模数两两互质,所以设 w_i=\dfrac{m_i}{b_i},则 r_i\cdot w_i\equiv 1\pmod {a_i}

此时求 w_i 即相当于求逆元,解得 w_i ,则 m_i=w_i\cdot b_i,x_i = m_i\cdot r_i

综上得方程组的解为(这里的逆元为模 a_i 意义下的):

x \equiv \sum\limits_{i=1}^n b_i \cdot r_i \cdot [r_i]^{-1}\mid_{a_i} \pmod p
for(int i=1;i<=n;i++) cin>>a[i]>>b[i],x*=a[i];
for(int i=1;i<=n;i++)
{
    int r=x/a[i];
    ans+=(b[i]*r*inv(r,a[i]))%x;
}

6.2 扩展中国剩余定理(EXCRT)

当不保证模数两两互质时,此时 r_ia_i 并不互质,所以不会有a_i 意义下的逆元,所以要换一种思路,每次合并两个同余方程。

假设现在要合并 \begin{cases} x \equiv b_1 \pmod {a_1} \\ x \equiv b_2 \pmod {a_2}\end{cases},我们要先找到一个解 x

变换一下 x=k_1\cdot a_1+b_1=k_2\cdot a_2+b_2,移项得 k_1\cdot a_1-k_2\cdot a_2=b_2-b_1,此时相当于不定方程,用扩展欧几里得法求解 k_1,k_2,此时得到最小整数解 x_0

显然我们将两个同余方程合并为 x\equiv x_0\pmod {\mathrm{lca(a_1,a_2)}} 即可,最后合并成一个同余方程,答案即得。

for(register signed i=2;i<=n;++i)
{
    int x,y,d;d=exgcd(x,y,a[i-1],a[i]);
    x*=(b[i]-b[i-1])/d;
    a[i]=a[i-1]*a[i]/d;
    b[i]=((x*a[i-1]+b[i-1])%a[i]+a[i])%a[i];
}
long long ans=b[n];cout<<ans<<'\n';return 0;

6.3 有解条件

我们发现当保证模数两两互质时,使用 CRT 不会出现无解的情况,但是当模数不是两两互质,使用 EXCRT 时,需要求解一个不定方程,根据裴属定理我们可以知道当 \gcd(a_1,a_2) \nmid (b_2-b_1) 时,方程无解,此时整体也无解。

所以模数两两互质是有解的充分不必要条件。

例题:
P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪
P3868 [TJOI2009] 猜数字
P4777 【模板】扩展中国剩余定理(EXCRT)

参考资料:

同余式-百度百科

同余方程详解-羊博士粉丝团代理团长

裴蜀定理-百度百科

扩展欧几里得算法-百度百科

算法学习笔记(8):拓展欧几里得-Pecco

乘法逆元-百度百科

算法学习笔记(9):逆元-Pecco

费马小定理-百度百科

费马小定理(易懂)-四年rain

孙子定理-百度百科

算法学习笔记(10): 中国剩余定理-Pecco

扩展中国剩余定理-阮行止