扩欧,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; }