Re:从零开始的同余问题

· · 个人记录

同余

在开始前必须要说明,涉及同余的变量和参量一般都为整数或正整数。

拓展欧几里得算法

首先我们知道,朴素欧几里得算法的原理是:gcd(a,b)=gcd(b,a\bmod b)

于是便可得到快速求解 ax+by=gcd(a,b) 的一种有效方法,我们称之为 \rm {exgcd},时间复杂度是 O(\log\limits a)

完全看懂上述推导过程就来写模板练手吧 ~

注意函数内引用,代码如下:

#include<bits/stdc++.h>
using namespace std;
int a,b,x,y;
void exgcd(int a,int b,int &x,int &y){
    if(!b){
        x=1;
        y=0;
        return ;
    }
    exgcd(b,a%b,y,x); //x1=y2,y1=x2,y1 之后再处理 
    y=y-a/b*x; //y1=x2-a/b*y2 
}
int main()
{
    cin>>a>>b;
    exgcd(a,b,x,y);
    cout<<x<<' '<<y;
    return 0;
}

非常简短,这就是数论的魅力 ~

不定方程

接上文,我们已经知道不定方程: ax+by=gcd(a,b) 的解法。但这还远远不够,我们想知道 c\in\mathbb{Z} 时,不定方程:ax+by=c 的解法。

当然,该不定方程可能无解,下面介绍判断是否有解的裴蜀定理。

线性同余方程

乘法逆元

众所周知,除法是乘法运算的逆运算,用于抵消乘法,而除以一个数相当于乘以这个数的倒数。

同余问题中,求倒数是很有价值的。假如要求 \frac ba \bmod {p},将 b,\frac 1a 分别对 p 取余后相乘即可。

但是同余式不满足同除性,因此取倒数就不仅仅是 \frac 1a 那样简单了。

于是便诞生了 乘法逆元 这一分块。

同余方程组

高次同余方程

拓展欧拉定理

不管那么多,拓展欧拉定理给予我们将 a^b\pmod p 降幂的工具,整理得:

a^b\equiv\begin{cases} a^{b\bmod \phi(p)}&gcd(a,p)=1\\a^b& gcd(a,p)\ne1,b\le\phi(p)\\a^{(b\bmod \phi(p))+\phi(p)}& gcd(a,p)\ne1,b>\phi(p)\end{cases}\pmod p

第一种情况就是朴素欧拉定理,不再赘述。

而第二种情况则代表 b 足够小了没必要降幂,用常规方法直接解决即可。