P5656 【模板】二元一次不定方程 (exgcd)
\[ax+by=d\\
ax_1+by_1=c\\
x_1=\frac{x*c}{gcd(a,b)},y_1=\frac{y*c}{gcd(a,b)}\\
对于最小正整数解有:x_1+\lambda\frac{b}{gcd(a,b)}>0\qquad y_1-\lambda\frac{a}{gcd(a,b)}>0\\
解得:\left\lceil\frac{-x_1+1}{\frac{b}{gcd(a,b)}}\right\rceil\le\lambda\le\left\lfloor\frac{y_1-1}{\frac{a}{gcd(a,b)}}\right\rfloor
\]
//正整数解:x>0,y>0
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9')x=(x<<3)+(x<<1)+ch-48,ch=getchar();
return x*f;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1,y=0;
return a;
}
ll d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main(){
int T;
ll a,b,c,d,x,y,tmp,l,r,X,Y;
T=read();
while(T--){
a=read(),b=read(),c=read();
d=exgcd(a,b,x,y);
if(c%d!=0){
puts("-1");
continue;
}
tmp=c/d;
x*=tmp,y*=tmp;
// printf("x=%d y=%d\n",x,y);
l=ceil((double)(-x+1)/(double)(b/d));
r=floor((double)(y-1)/(double)(a/d));
if(l>r){
printf("%lld %lld\n",x+l*(b/d),y-r*(a/d));
}
else{
printf("%lld ",(r-l+1));
X=x+l*(b/d);
Y=y-r*(a/d);
printf("%lld %lld ",X,Y);
printf("%lld %lld\n",(c-b*Y)/a,(c-a*X)/b);
}
}
return 0;
}