扩展欧几里得算法
引入
日常生活中我们会遇到一些不定方程,注意本文中所考虑的解都是整数解,如:
\[3x+y=5
\]
我们可以知道这个方程有解,如:
\[\begin{cases}x=1\\y=2\end{cases},\begin{cases}x=2\\y=-1\end{cases},\begin{cases}x=3\\y=-4\end{cases}......\begin{cases}x=1+k\\y=2-3k\end{cases}
\]
我们可以知道这个方程有无数的整数解。
算法
我们的扩欧就是来解决形如:
\[ax+by=\gcd(a,b)
\]
这一类 \(x,y\) 整数解的求解问题的。
我们可以知道 \(\gcd(a,b)=\gcd(b,a\%b)\)。所以我们在设一个方程:
\[bx'+(a\%b)y'=\gcd(b,a\%b)
\]
所以我们有:
\[ax+by=bx'+(a\%b)y'
\]
\[ax+by=bx'+(a-\lfloor\frac{a}{b}\rfloor\cdot b)y'
\]
\[ax+by=ay'+b\cdot(x'-\lfloor\frac{a}{b}\rfloor\cdot y')
\]
所以 \(x=y',y=x'-\lfloor\frac{a}{b}\rfloor\cdot y'\)
递归求解即可:
#pragma GCC optimize("Ofast","-funroll-loops","-fdelete-null-pointer-checks")
#pragma GCC target("ssse3","sse3","sse2","sse","avx2","avx")
#include<bits/stdc++.h>
#define int long long
using namespace std;
int read() {
char ch=getchar();
int f=1,x=0;
while(ch<'0'||ch>'9') {
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
int a,b,x,y;
void exgcd(int a,int b,int &x,int &y) {
if(b==0) {
x=1,y=0;
return ;
}
exgcd(b,a%b,x,y);
int xx=y;
int yy=x-a/b*y;
x=xx;
y=yy;
}
signed main() {
a=read();b=read();
exgcd(a,b,x,y);
cout<<x<<" "<<y<<endl;
return 0;
}