ABC408G 题解

我的 MO 还是太菜了。

注意到,当 \(\dfrac AB < 1 < \dfrac CD\) 时,\(p = q = 1\)

现在只需处理都是假分数和都是真分数的情况了。

\(1 < \dfrac AB < \dfrac CD\),我们想把它们变成真分数,所以令 \(k = \min \left( \left \lfloor \dfrac AB \right \rfloor, \left \lfloor \dfrac CD \right \rfloor \right)\),然后让它们都减 \(k\)

此时不等式变为:

\[\dfrac{A - kB}{B} < \dfrac{p - kq}{q} < \dfrac{C - kD}{D} \]

此时如果有 \(L < 1 < R\),我们就做完了。不然此时它们都是真分数,我们只需让它们都取倒数,此时不等式变为:

\[\dfrac DC < \dfrac qp < \dfrac BA \]

递归下去即可。注意 \(A = B\)\(C = D\) 的情况。

#include <algorithm>
#include <iostream>
#include <utility>

using namespace std;
using i64 = long long;

struct Solution {
    pair<i64, i64> solve(i64 a, i64 b, i64 c, i64 d)
    {
        if (a < b && c > d)
            return { 1, 1 };
        else if (a == 0)
            return { 1, d / c + 1 };
        else if (c <= d) {
            auto [p, q] = solve(d, c, b, a);
            return { q, p };
        } else {
            i64 minus = min(a / b, c / d);
            auto [p, q] = solve(a - minus * b, b, c - minus * d, d);
            return { p + minus * q, q };
        }
    }

    void main()
    {
        i64 a, b, c, d;
        cin >> a >> b >> c >> d;
        cout << solve(a, b, c, d).second << '\n';
    }
};

int main()
{
    int t;
    cin >> t;

    while (t-- > 0)
        Solution().main();

    return 0;
}
posted @ 2025-08-02 16:09  David9006  阅读(7)  评论(0)    收藏  举报