Description
给定 (a,b le 2 imes 10^6),构造 (c,d,e,f) 满足 (c/d-e/f=a/b),且 (d,f<b),(c,d,e,f le 4 imes 10^{12})
Solution
原式变形得
[frac {cf-de} {df} = frac a b =frac {a'} {b'},quad a'=frac a {(a,b)}, quad b'=frac b {(a,b)}
]
若 (b eq b'),则令 (c=a'+b', d=b', e=1,f=1) 即可
若 (b=b'),考虑将 (b) 分解为两个互质的部分 (d,f) 且 (d eq b, f eq b)
以 (c,e) 为未知量,解不定方程 (cf-ed=a) 即可
为了方便,先将 (c,(-e)) 解出,然后对于 (c,e),当有负数时,循环将 (c+=d,e+=f) 即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define LL long long
vector <int> prime;
LL gcd(LL a,LL b){
if(b==0) return a;
else return gcd(b,a%b);
}
LL exgcd(LL a,LL b,LL &x,LL &y){
if(b==0){
x=1;y=0;
return a;
}
LL r=exgcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return r;
}
void solve()
{
int a,b;
scanf("%lld%lld",&a,&b);
if(__gcd(a,b)>1)
{
int g=__gcd(a,b);
a/=g; b/=g;
printf("%lld %lld 1 1
",a+b,b);
}
else
{
for(int d:prime) if(d*d<=b && b%d==0)
{
int f=b/d;
int d0=d;
while(f%d0==0) f/=d0, d*=d0;
if(f==1) continue;
int c,e;
exgcd(f,d,c,e);
e=-e;
while(c+d*10000<=0 || e+f*10000<=0)
{
c+=d*10000;
e+=f*10000;
}
while(c+d*1000<=0 || e+f*1000<=0)
{
c+=d*1000;
e+=f*1000;
}
while(c+d*100<=0 || e+f*100<=0)
{
c+=d*100;
e+=f*100;
}
while(c+d*10<=0 || e+f*10<=0)
{
c+=d*10;
e+=f*10;
}
while(e<=0 || c<=0)
{
c+=d;
e+=f;
}
c*=a;
e*=a;
if((c*f-d*e)*b!=a*d*f) cout<<"failed"<<endl;
printf("%lld %lld %lld %lld
",c,d,e,f);
return;
}
/*for(int f=2;f*f<=b;f++) if(b%f==0)
{
int d=b/f;
if(d==1) continue;
if(__gcd(f,d)>1) continue;
int c,e;
exgcd(f,d,c,e);
e=-e;
while(e<=0 || c<=0)
{
c+=d;
e+=f;
}
c*=a;
e*=a;
if((c*f-d*e)*b!=a*d*f) cout<<"failed"<<endl;
cout<<c<<" "<<d<<" "<<e<<" "<<f<<endl;
return;
}*/
puts("-1 -1 -1 -1");
}
}
signed main()
{
ios::sync_with_stdio(false);
for(int i=2;i<=1500;i++)
{
int flag=1;
for(int j=2;j<i;j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag) prime.push_back(i);
}
int t;
scanf("%lld",&t);
while(t--)
{
solve();
}
}