文章目录
R e s u l t Result Result
H y p e r l i n k Hyperlink Hyperlink
https://www.luogu.com.cn/problem/P5656
D e s c r i p t i o n Description Description
T
T
T组询问
求方程
a
x
+
b
y
=
c
ax+by=c
ax+by=c的正整数解个数,
x
x
x最小的正整数解,
y
y
y最小的正整数解,
x
x
x最大的正整数解,
y
y
y最大的正整数解
数据范围: T ≤ 2 × 1 0 5 , a , b , c ≤ 1 0 9 T\leq 2\times 10^5,a,b,c\leq 10^9 T≤2×105,a,b,c≤109
S o l u t i o n Solution Solution
首先根据裴蜀定理,必须满足 g c d ( a , b ) ∣ c gcd(a,b)|c gcd(a,b)∣c,方程才有整数解
然后我们可以用 E x g c d Exgcd Exgcd求出 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的一组整数解,显然,我们令 x , y x,y x,y都乘上 c g d c ( a , b ) \frac c{gdc(a,b)} gdc(a,b)c即可得到 a x + b y = c ax+by=c ax+by=c的一组整数解
然后考虑上下调整 x , y x,y x,y即可
C o d e Code Code
#include<cmath>
#include<cstdio>
#include<cctype>
#define LL long long
using namespace std;LL n,a,b,c,d,x,y,p,q,k;
inline LL read()
{
LL d=1,f=0;char c;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline LL gcd(LL x,LL y){return y?gcd(y,x%y):x;}
inline void Exgcd(LL a,LL b,LL &x,LL &y)
{
if(b==0) return (void)(x=1,y=0);
Exgcd(b,a%b,x,y);LL tmp=x;x=y;y=tmp-a/b*y;return;
}
signed main()
{
n=read();
while(n--)
{
a=read();b=read();c=read();d=gcd(a,b);
if(c%d) {puts("-1");continue;}
Exgcd(a,b,x,y);x*=c/d;y*=c/d;
p=b/d;q=a/d;
if(x<=0) k=ceil((1.0-x)/p),x+=p*k,y-=q*k;
else if(x>0) k=(x-1)/p,x-=p*k,y+=q*k;
if(y>0) printf("%lld %lld %lld %lld %lld\n",(y-1)/q+1,x,(y-1)%q+1,x+(y-1)/q*p,y);
else printf("%lld %lld\n",x,y+q*(LL)ceil((1.0-y)/q));
}
}