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
", 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
", c, d, e, f);
        }
    }

    return 0;
}
原文地址:https://www.cnblogs.com/jungu/p/13368379.html