結果

問題 No.2183 LCA on Rational Tree
ユーザー noya2noya2
提出日時 2023-01-07 19:46:21
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 259 ms / 2,000 ms
コード長 2,194 bytes
コンパイル時間 2,455 ms
コンパイル使用メモリ 211,848 KB
実行使用メモリ 6,820 KB
最終ジャッジ日時 2024-12-15 05:42:58
合計ジャッジ時間 3,468 ms
ジャッジサーバーID
(参考情報)
judge2 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 8 ms
6,820 KB
testcase_01 AC 126 ms
6,820 KB
testcase_02 AC 259 ms
6,816 KB
testcase_03 AC 38 ms
6,816 KB
testcase_04 AC 16 ms
6,816 KB
testcase_05 AC 28 ms
6,816 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include<bits/stdc++.h>
#include<atcoder/math>
#define rep(i,n) for (int i = 0; i < int(n); ++i)
using namespace std;
using ll = long long;
const ll inf = 2e18;
void fast_io(){cin.tie(0); ios::sync_with_stdio(0); cout<<fixed<<setprecision(20);}

void nxt(ll &p, ll &q, vector<ll> &divs){
    // nxt = (p+x) / (q+x)
    ll x = inf;
    for (ll d : divs){
        if ((q-p) % d == 0) x = min(x, d - (p % d));
    }
    ll g = gcd(p+x, q+x);
    p = (p+x) / g, q = (q+x) / g;
}

vector<ll> primes;

void solve(){
    ll p1, q1, p2, q2; cin >> p1 >> q1 >> p2 >> q2;
    auto init = [&](ll p, ll q){
        vector<ll> ps;
        ll n = q - p;
        for (ll d : primes){
            if (d * d > n) break;
            if (n == 1) break;
            if (n % d != 0) continue;
            while (n % d == 0) n /= d;
            ps.emplace_back(d);
        }
        if (n > 1) ps.emplace_back(n);
        vector<pair<ll,ll>> a;
        a.emplace_back(p,q);
        do {
            nxt(p,q,ps);
            a.emplace_back(p,q);
        } while (q - p > 1);
        a.emplace_back(inf,inf+1);
        return a;
    };
    auto a1 = init(p1,q1), a2 = init(p2,q2); //for (auto a : a1) printf("%lld %lld\n", a.first,a.second); printf("\n");
    int n1 = a1.size(), n2 = a2.size();
    rep(i1,n1-1) rep(i2,n2-1){
        ll ip1 = a1[i1].first, iq1 = a1[i1].second;
        ll ip2 = a2[i2].first, iq2 = a2[i2].second;
        if (iq1 - ip1 != iq2 - ip2) continue;
        ll np1 = a1[i1+1].first, nq1 = a1[i1+1].second;
        ll np2 = a2[i2+1].first, nq2 = a2[i2+1].second;
        // (iq1 + x1) / (ip1 + x1) == (iq2 + x2) / (ip2 + x2)
        // 0 <= x1 < lim1, 0 <= x2 < lim2
        ll lim1 = (iq1 - ip1) / (nq1 - np1) * np1 - ip1;
        ll lim2 = (iq2 - ip2) / (nq2 - np2) * np2 - ip2;
        ll x1 = max(0LL, ip2 - ip1);
        ll x2 = ip1 - ip2 + x1;
        if (x1 < lim1 && x2 < lim2){
            printf("%lld %lld\n", ip1+x1,iq1+x1);
            return ;
        }
    }
}

int main(){
    fast_io();
    primes.reserve(3401);
    for (int p = 2; p * p <= int(1e9); p++) if (atcoder::internal::is_prime_constexpr(p)) primes.push_back(p);
    int t = 1; cin >> t;
    while(t--) solve();
}
0