Description
给定 \(a,b \le 2\times 10^6\),构造 \(c,d,e,f\) 满足 \(c/d-e/f=a/b\),且 \(d,f<b\),\(c,d,e,f \le 4 \times 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 \neq b'\),则令 \(c=a'+b', d=b', e=1,f=1\) 即可
若 \(b=b'\),考虑将 \(b\) 分解为两个互质的部分 \(d,f\) 且 \(d\neq b, f\neq 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\n",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\n",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();
}
}