浅谈 exgcd
众所周知欧几里得算法是:
\[\gcd(a,b)=\gcd(b,a\bmod b)
\]
也叫辗转相除法。
拓展欧几里得算法(exgcd
),可以用来找到形如 \(ax+by=\gcd(a,b)\) 的方程的一组特解。
由裴蜀定理知,原方程一定有解。
我们利用辗转相除法(普通欧几里得算法)。
我们设 \(d=\gcd(a,b)\)。
我们可以知道,我们辗转相除法的边界是 \(a=d,b=0\),此时我们可以知道 \(a\) 就是最大公约数,我们还可以知道,在这时一定有一解为 \(x=1,y=0\),即 \(1\times a+0\times b=d\)。
我们知道 \(\gcd(a,b)=\gcd(b,a\bmod b)\),如果我们可以推导出每一次的解 \(x\) 和 \(y\),与相除后的解 \(x'\) 和 \(y'\) 的关系;我们就可以算出其中的一个解了,(\(x\) 和 \(y\) 相当于是 \(a\) 和 \(b\) 的解,\(x'\) 和 \(y'\) 是 \(a\) 变成了 \(b\),\(b\) 变成了 \(a\bmod b\) 时的解(辗转相除))。
轻易得知:
\(\begin{cases} ax+by=d\\ bx'+(a\bmod b)y'=d \end{cases}\)
则:
\[\begin{aligned}
bx'+\left(a-b\left\lfloor\dfrac{a}{b}\right\rfloor\right)y'&=d\\
bx'+ay'-b\left\lfloor\dfrac{a}{b}\right\rfloor y'&=d\\
ay'+b(x'-\left\lfloor\dfrac{a}{b}\right\rfloor y')&=d\\
\text{解得:}&\begin{cases}
x=y'\\y=x'-\left\lfloor\dfrac{a}{b}\right\rfloor y'
\end{cases}
\end{aligned}
\]
然后我们知道 \(x\) 与 \(x'\), \(y\) 与 \(y'\), 的关系后就可以求解了:
#include<iostream>
#include<cstdio>
using namespace std;
void exgcd(int a,int b,int& x,int& y) //x.y也可以用pair返回,这里用了引用
{
if (!b){x=1;y=0;return ;} //边界
gcd(b,a%b); //辗转相除
int tmp=y;y=x-(a/b)*y;x=tmp; //套公式
}
int main()
{
int a,b,x,y;
scanf("%d %d",&a,&b);
exgcd(a,b,x,y);
printf("%d %d",x,y);
return 0;
}
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/12853932.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ