2020牛客多校第三场F-Fraction Construction-Problem

https://ac.nowcoder.com/acm/contest/5668/F

题意

给定a,b,求(frac{c}{d}-frac{e}{f}=frac{a}b),且d,f小于b,且c,e小于$4 imes 10^{12} $

题解

如果a,b不互质,答案为(a' + 1, b', 1, b'),其中(a',b')为化简后的分子分母

如果a,b互质,对于b分解质因子,(frac{cf-de}{df}=frac{a}b),把b分解为互质的两个数,分别赋值给d,f,拓欧求解(cf+de=gcd(d,f)=1),拓欧求出来的数必定一正一负,如果c为负交换一下即可。解出来的结果乘以a即为答案。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct READ {
    inline char read() {
    #ifdef _WIN32
        return getchar();
    #endif
        static const int IN_LEN = 1 << 18 | 1;
        static char buf[IN_LEN], *s, *t;
        return (s == t) && (t = (s = buf) + fread(buf, 1, IN_LEN, stdin)), s == t ? -1 : *s++;
    }
    template <typename _Tp> inline READ & operator >> (_Tp&x) {
        static char c11, boo;
        for(c11 = read(),boo = 0; !isdigit(c11); c11 = read()) {
            if(c11 == -1) return *this;
            boo |= c11 == '-';
        }
        for(x = 0; isdigit(c11); c11 = read()) x = x * 10 + (c11 ^ '0');
        boo && (x = -x);
        return *this;
    }
} in;

const int N = 2e5 + 50;
vector<ll> S;
void get_S(int x) {
    S.clear();
    for (int i = 2; i * i <= x; i++) {
        if (x % i) continue;
        int tmp = 1;
        while (x % i == 0) {
            tmp *= i;
            x /= i;
        }
        S.push_back(tmp);
    }
    if (x != 1) S.push_back(x);
}
void exgcd(ll a, ll b, ll &x, ll &y) {
    if (!b) x = 1, y = 0;
    else {
        exgcd(b, a % b, x, y);
        ll tmp = y;
        y = x - a / b * y;
        x = tmp;
    }
}
ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}
int main() {
    int t;
    in >> t;
    while (t--) {
        ll a, b;
        in >> a >> b;
        if (b == 1) {
            puts("-1 -1 -1 -1");
            continue;
        }
        ll x = gcd(a, b);
        if (x == 1) {
            get_S(b);
            if (S.size() == 1) {
                puts("-1 -1 -1 -1");
                continue;
            }
            else {
                ll c, d, e, f;
                d = S[0];
                f = b / d;
                exgcd(f, d, c, e);
                if (c < 0) {
                    swap(c, e);
                    swap(d, f);
                }
                ll x = c / d;
                c -= x * d;
                e += x * f;
                if (c * a > 1e12 || -e * a > 1e12) puts("-1 -1 -1 -1");
                else {
                    printf("%lld %lld %lld %lld
", 1ll * c * a, d, -1ll * e * a, f);
                }
            }
        }
        else {
            b /= x;
            a /= x;
            printf("%lld %lld %lld %lld
", a + 1, b, 1ll, b);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/artoriax/p/13589878.html