欧几里得与拓展欧几里得算法学习笔记
欧几里得与拓展欧几里得
欧几里得算法
欧几里得算法是一种快速求出最大公约数的算法。
内容
对于任意的两个整数 \(a,b\),其最大公约数 \(\gcd(a,b) = \gcd(b,a \bmod b)\)。
证明
- 对于 \(b>a\) 的情况 ,显然成立。
- 因此只考虑 \(b<a\) 的情况。设 \(a=q \times b +p,\left( q=\left\lfloor\dfrac{a}{b}\right\rfloor,p=a-b \times\left\lfloor\dfrac{a}{b}\right\rfloor=a\bmod b \right)\)
- 对于 \(g_1=\gcd(a,b)\),显然存在 \(g_1\mid a,g_1\mid b\),由此易得 \(g_1\mid p\),其中\(\ g_1\mid a\) 表示 $a \bmod g_1 =0\ $。
- 又因为 \(p=a\bmod b\),所以对于 \(a,b\) 的最大公约数 \(g_1\),同样满足 \(g_1\mid a\bmod b,g_1\mid b\),即 \(b,a\bmod b\) 的最大公约数至少为 \(g_1\),即 \(\gcd(b,a \bmod b) > g1=\gcd(a,b)\)。
- 反过来,对于 \(b,a\bmod b\) 的最大公约数 \(g_2=\gcd(b,a\bmod b)\),同样满足 \(g_2 \mid a,g2 \mid b\),即 \(\gcd(a,b)>g2=\gcd(b,a \bmod b)\)。
- 因此 \(\gcd(a,b)=\gcd(b,a \bmod b)\) 证明成立。
代码实现
#include <bits/stdc++.h>
using namespace std;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int main(){
int a,b;cin>>a>>b;
cout<<gcd(a,b)<<endl;return 0;
}
拓展欧几里得算法
内容
求解不定方程 $$ax+by=\gcd(a,b)$$
证明
令 $$a\ x_1+b\ y_1=\gcd(a,b)$$
\[b\ x_2+(a \bmod b)y_2=\gcd(b,a \bmod b)
\]
根据欧几里得算法可知 $$\gcd(a,b)=\gcd(b,a\bmod b)$$
所以可得 $$a\ x_1+b\ y_1=b\ x_2+(a \bmod b)\ y_2=b\ x_2+ \left(a\ –\ b \ \left\lfloor\dfrac{a}{b}\right\rfloor \right) y_2=a\ y_2+b\ x_2-b^2\ \left\lfloor\dfrac{a}{b}\right\rfloor y_2$$
解得:\(\begin{cases}x_1=y_2 \\ y_1=x_2-\left\lfloor\dfrac{a}{b}\right\rfloor y_2\end{cases}\)
即方程的一组解。
代码实现
求关于 \(x\) 的同余方程 \(ax \equiv 1 \pmod{b}\) 的最小正整数解。
直接套板子即可。
#include <bits/stdc++.h>
using namespace std;int k,x,y;
void exgcd(int a,int b){
if(b==0){x=1;y=0;return;}
exgcd(b,a%b);k=x;x=y;y=k-a/b*y;return;
}int main(){
int n,m;cin>>n>>m;exgcd(n,m);
cout<<(x+m)%m<<endl;return 0;
}