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

浙公网安备 33010602011771号