2020牛客多校 第三场F
思路:
化简 a/b ,g = gcd(a, b)。分情况讨论:
1. b / g != b ,则由(a + b) / b - 1= a / b可推出,c = (a + b) / g, d = b / g, e = 1, f = 1
2.b / g == b 即 g == 1,则a与b互质。此时可推出 cf - ed = a, df = b 。cf - ed = a有解当且仅当 a % gcd(f, d) == 0,由于a与b互质,则只有f与d互质的时候方程才有解。可推出当b = 1,b是质数或者b是质数的幂的时候,方程无解,输出“-1 -1 -1 -1”。否则,用欧几里得解出方程,输出方程的解即可。
Code:
#pragma GCC optimize(3) #pragma GCC optimize(2) #include <map> #include <set> #include <array> #include <queue> #include <stack> #include <vector> #include <cstdio> #include <cstring> #include <sstream> #include <iostream> #include <stdlib.h> #include <algorithm> #include <unordered_map> using namespace std; typedef long long ll; typedef pair<int, int> PII; #define Time (double)clock() / CLOCKS_PER_SEC #define sd(a) scanf("%d", &a) #define sdd(a, b) scanf("%d%d", &a, &b) #define slld(a) scanf("%lld", &a) #define slldd(a, b) scanf("%lld%lld", &a, &b) const int N = 2e6 + 10; const ll M = 4e12; const int mod = 998244353; int primes[N], mind[N], cnt = 0; bool st[N]; void get(int n) { // st[1] = true; primes[0] = 1; for (int i = 2; i <= n; i++) { if (!st[i]) { primes[++cnt] = i; mind[i] = i; } for (int j = 1; primes[j] <= n / i; j++) { st[i * primes[j]] = true; mind[i * primes[j]] = primes[j]; if (i % primes[j] == 0) { break; } } } } ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; } ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1, y = 0; return a; } ll d = exgcd(b, a % b, y, x); y -= (a / b) * x; return d; } int t; ll a, b, c, d, e, f, g, x, y; int main() { #ifdef ONLINE_JUDGE #else freopen("/home/jungu/code/in.txt", "r", stdin); // freopen("/home/jungu/code/out.txt", "w", stdout); // freopen("/home/jungu/code/out.txt","w",stdout); #endif // ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); sd(t); get(N - 10); while (t--) { slldd(a, b); int g = gcd(a, b); if (g > 1) { c = (a + b) / g, d = b / g, e = 1, f = 1; printf("%lld %lld %lld %lld\n", c, d, e, f); } else { if(!st[b]){ puts("-1 -1 -1 -1"); continue; } c = -1, d = -1, e = -1, f = -1; for(int i = 2; i <= b / i; i ++){ if(b % i == 0){ d = 1, f = b; while(f % i == 0){ f /= i, d *= i; } if(f == 1){ d = -1, f = -1; break; } g = exgcd(f, d, c, e); while(c <= 0 || e >= 0){ e -= f; c += d; } c *= a, e *= a; e = -e; break; } } printf("%lld %lld %lld %lld\n", c, d, e, f); } } return 0; }