結果
問題 |
No.3073 Fraction Median
|
ユーザー |
👑 |
提出日時 | 2025-03-21 23:15:15 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 2,464 bytes |
コンパイル時間 | 1,128 ms |
コンパイル使用メモリ | 104,136 KB |
実行使用メモリ | 14,776 KB |
最終ジャッジ日時 | 2025-03-21 23:15:22 |
合計ジャッジ時間 | 6,892 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 4 TLE * 1 -- * 13 |
ソースコード
#include <iostream> #include <vector> #include <algorithm> using namespace std; // ユーザ定義の gcd 関数(ユークリッドの互除法) long long gcd(long long a, long long b) { while (b != 0) { long long temp = a % b; a = b; b = temp; } return a; } // グローバル変数 int N; vector<long long> A; // __int128 を使って積の比較を安全に行う関数 bool comp(long long x_c, long long x_d, long long y_c, long long y_d) { __int128 lhs = (__int128)x_c * y_d; __int128 rhs = (__int128)y_c * x_d; return lhs <= rhs; } // check 関数: 与えられた val に対して (bool, (max_c, max_d)) を返す pair<bool, pair<long long, long long>> check(long long val) { long long max_c = 0, max_d = 1; long long cnt = 0; for (int i = 0; i < N; i++) { int ok = 0, ng = N; // バイナリサーチ: 条件を満たす最大の ok を求める while (ng - ok > 1) { int mid = (ok + ng) / 2; // Python の comp((A[mid-1], A[i]), (val, 10**18)) に対応 if (comp(A[mid - 1], A[i], val, 1000000000000000000LL)) { ok = mid; } else { ng = mid; } } cnt += ok; // 条件により最大の分数 (max_c, max_d) を更新 if (ok > 0 && comp(max_c, max_d, A[ok - 1], A[i])) { max_c = A[ok - 1]; max_d = A[i]; } } // ペア数が N*(N-1)/2 未満なら true、それ以外なら false を返す if (cnt < (long long)N * (N - 1) / 2) { return {true, {max_c, max_d}}; } else { return {false, {max_c, max_d}}; } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); // 入力 cin >> N; A.resize(N); for (int i = 0; i < N; i++) { cin >> A[i]; } // ソート sort(A.begin(), A.end()); // main のバイナリサーチ: [0, 10^18+1) の範囲で val を探索 long long ok_val = 0, ng_val = 1000000000000000000LL + 1; while (ng_val - ok_val > 1) { long long mid = (ok_val + ng_val) / 2; if (check(mid).first) { ok_val = mid; } else { ng_val = mid; } } // 答えの分数を得る auto ans = check(ng_val).second; long long g = gcd(ans.first, ans.second); cout << (ans.first / g) << " " << (ans.second / g) << "\n"; return 0; }