1. 程式人生 > 實用技巧 >2020牛客多校 第三場F

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; }