exgcd
扩展欧几里得算法
扩展欧几里得算法\((Extended\space\space Euclidean\space\space algorithm, EXGCD)\),常用于求 \(ax+by=\gcd(a,b)\) 的一组可行解。
证明过程
\[\begin{array}{l}
设ax_1+by_1=\gcd(a,b)\\
bx_2+(a\mod b)y_2=\gcd(b,a\mod b)\\\\
\because \gcd(a,b)=\gcd(b,a\mod b)\\
\therefore ax_1+by_1=bx_2+(a\mod b)y_2\\
又\because a\mod b=a-(\left \lfloor \frac{a}{b} \right \rfloor \times b ) \\
\therefore ax_1+by_1=bx_2+(a-(\left \lfloor \frac{a}{b} \right \rfloor \times b ))y_2\\
ax_1+by_1=ay_2+bx_2-\left \lfloor \frac{a}{b} \right \rfloor \times by_2=ay_2+b(x_2-\left \lfloor \frac{a}{b} \right \rfloor y_2)\\
\because a=a,b=b\\
\therefore x_1=y_2,y_1=x_2-\left \lfloor \frac{a}{b} \right \rfloor y_2
\end{array} \]
P5656 【模板】二元一次不定方程 (exgcd)
#include<bits/stdc++.h>
#define int long long
#define il inline
#define ri register int
#define ru register unsigned int
#define debug printf("Now is %d\n",__LINE__);
#define random(a,b) ((a)+rand()%((b)-(a)+1))
using namespace std;
il int read()
{
int as=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') as=(as<<3)+(as<<1)+(ch^48),ch=getchar();
return as*f;
}
il void wt(int x)
{
if(!x) return;
wt(x/10),putchar(x%10+'0');
}
il int exgcd(int a,int b,int &x,int &y)
{
if(b==0) return x=1,y=0,a;
int g=exgcd(b,a%b,y,x);y-=a/b*x;
return g;
}
signed main()
{
int T=read();
for(ru o=1;o<=T;++o)
{
int a,b,c,x,y,x1_,y1_,gcd,dx,dy,sl,sr;
a=read(),b=read(),c=read(),gcd=exgcd(a,b,x,y);
if(c%gcd!=0) {printf("-1\n");continue;}//无整数解
dx=b/gcd,dy=a/gcd,x1_=x*c/gcd,y1_=y*c/gcd;
sl=ceil((-x1_+1)*1.0/(dx*1.0)),sr=floor((y1_-1)*1.0/(dy*1.0));
//有整数解但无正整数解
if(sl>sr){wt(x1_+sl*dx),putchar(' '),wt(y1_-sr*dy),putchar('\n');}
else //有正整数解
{
wt(sr-sl+1),putchar(' '),
wt(x1_+sl*dx),putchar(' '),wt(y1_-sr*dy),putchar(' '),
wt(x1_+sr*dx),putchar(' '),wt(y1_-sl*dy),putchar('\n');
}
}
return 0;
}

浙公网安备 33010602011771号