题目链接:https://ac.nowcoder.com/acm/contest/5668/F
题目描述
There are t queries.
In each query, you are given two positive integers a a a and b b b ( a , b ≤ 2 × 1 0 6 ) (a, b\leq2×10^6) (a,b≤2×106)
Please print a line consists of four positive integers c , d , e , f c,d,e,f c,d,e,fsatisfying the following constraints:
If there are multiple solutions, you can print anyone.
If there are no solution, please print “-1 -1 -1 -1” in this line.
输入描述
The first line contains one integer t t t ( 1 ≤ t ≤ 1 0 5 ) (1\leq t\leq 10^5) (1≤t≤105) — the number of test cases.
The only line of each test case contains two integers a a a and b b b ( a , b ≤ 2 × 1 0 6 ) (a, b\leq2×10^6) (a,b≤2×106)
输出描述
For each test case print four integers — c , d , e , f c,d,e,f c,d,e,f. If there are no solution, c , d , e , f c,d,e,f c,d,e,f should all be − 1 -1 −1.
输入
3 3 3
4 4 4 1 1 1
1 1 1 6 6 6
37 37 37 111 111 111
输出
− 1 -1 −1 − 1 -1 −1 − 1 -1 −1 − 1 -1 −1
1 1 1 2 2 2 1 1 1 2 2 2
145 145 145 87 87 87 104 104 104 78 78 78
在d,f找到之后就开始找c和e了。
已知d*f = b,通分后可得 c × f − e × d = a c×f-e×d=a c×f−e×d=a(d、f、a都知道,求c、e),求解c和e,即用扩展欧几里得算法。
注意:求出c和e之后判断一下谁正谁负,毕竟d和f和b的两个相异质因数是不知道对应谁的,可以通过c和e的正负性判断。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pdd;
#define INF 0x7f7f7f
#define mem(a,b) memset(a , b , sizeof(a))
#define FOR(i, x, n) for(int i = x;i <= n; i++)
// const ll mod = 1e9 + 7;
const int maxn = 5e6 + 10;
// const double eps = 1e-6;
int prime[1005]; // 素数数组
bool is_prime[maxn]; // is_prime[i]表示i为素数
int p;
void sieve() // 返回n以内的素数个数
{
int n = maxn;
mem(is_prime, true);
is_prime[0] = is_prime[1] = false;
is_prime[2] = true;
for(int i = 2;i * i <= n; i++)
{
if(is_prime[i])
{
prime[++p] = i;
for(int j = 2 * i;j <= n; j += i)
{
is_prime[j] = false;
}
}
}
}
ll gcd(ll a, ll b)
{
return b == 0 ? a : gcd(b, a % b);
}
ll ex_gcd(ll a, ll b, ll &x, ll &y)
{
ll res, t;
if(!b)
{
x = 1;
y = 0;
return a;
}
res = ex_gcd(b, a % b, x, y);
t = x;
x = y;
y = t - (a / b) * y;
return res;
}
ll solve_ex_gcd(ll a, ll b, ll c, ll &x, ll &y)
{
ll inv = ex_gcd(a, b, x, y);
if(c % inv)
{
x = -1;
y = -1;
return -1;
}
x *= (c / inv);
y *= (c / inv);
return 0;
}
void solve()
{
ll a, b;
cin >> a >> b;
ll k = gcd(a, b);
if(k != 1)
{
a /= k;
b /= k;
cout << a + 1 << " " << b << " " << 1 << " " << b << endl;
return ;
}
if(b == 1 || is_prime[b])
cout << "-1 -1 -1 -1" << endl;
else
{
ll tmp = 0, time = 0;
ll bb = b;
for(int i = 1;i <= p && bb != 1; i++) // 找两个素因数
{
if(bb % prime[i] == 0)
{
tmp = prime[i];
while(bb % prime[i] == 0)
{
time++;
bb /= prime[i];
}
break;
}
}
if(bb == 1)
{
cout << "-1 -1 -1 -1" << endl;
return ;
}
ll d = 1;
for(int i = 1;i <= time; i++)
{
d *= tmp; // b的一个因数
}
ll f = bb; // b的另一个因数
ll c = 0, e = 0;
solve_ex_gcd(f, d, a, c, e);
if(c < 0 && e > 0)
{
cout << e << " " << f << " " << -c << " " << d << endl;
}
else
cout << c << " " << d << " " << -e << " " << f << endl;
}
}
signed main()
{
ios_base::sync_with_stdio(false);
//cin.tie(nullptr);
//cout.tie(nullptr);
#ifdef FZT_ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#else
ios::sync_with_stdio(false);
sieve();
int T = 1;
cin >> T;
while(T--)
solve();
#endif
return 0;
}