扩欧,a+bx=c+dx,输出x>=0且y>=0,且a+bx最小的解。
要注意不能只保证x非负,还得看看能否保证y也非负。
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll;
ll a,b,c,d;
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
if(!b)
{
d=a;
x=1;
y=0;
}
else
{
exgcd(b,a%b,d,y,x);
y-=x*(a/b);
}
}
int main(){
// freopen("a.in","r",stdin);
cin>>b>>a>>d>>c;
ll x0,y0,D;
exgcd(b,d,D,x0,y0);
if((c-a)%D){
puts("-1");
return 0;
}
x0=x0*((c-a)/D);
x0=(x0%(d/D)+d/D)%(d/D);
y0=(a+b*x0-c)/d;
if(y0>=0){
cout<<a+x0*b<<endl;
return 0;
}
exgcd(d,b,D,x0,y0);
if((a-c)%D){
puts("-1");
return 0;
}
x0=x0*((a-c)/D);
x0=(x0%(b/D)+b/D)%(b/D);
y0=(d*x0+c-a)/b;
if(y0<0){
puts("-1");
return 0;
}
cout<<c+x0*d<<endl;
return 0;
}