結果
| 問題 |
No.2718 Best Consonance
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-01-31 19:47:00 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 332 ms / 4,000 ms |
| コード長 | 1,653 bytes |
| コンパイル時間 | 2,188 ms |
| コンパイル使用メモリ | 208,784 KB |
| 最終ジャッジ日時 | 2025-02-19 00:53:39 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 36 |
ソースコード
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
assert(2 <= n && n <= (int)2e5);
vector<int> a(n); vector<long long> b(n);
for (int i = 0; i < n; i++) {
cin >> a[i] >> b[i];
assert(1 <= a[i] && a[i] <= (int)2e5);
assert(1 <= b[i] && b[i] <= (long long)1e9);
}
int a_max = *max_element(a.begin(), a.end());
long long res = 0;
// 各 A[i] に対して最大の B[i] を対応付ける.
vector<long long> a_to_bmax(a_max + 1, -1);
for (int i = 0; i < n; i++) {
if (a_to_bmax[a[i]] == -1) {
a_to_bmax[a[i]] = b[i];
}
else {
// それと同時に A[i] = A[j] のタイプを先に処理する.
res = max(res, min(a_to_bmax[a[i]], b[i]));
a_to_bmax[a[i]] = max(a_to_bmax[a[i]], b[i]);
}
}
// A[i] と A[j] の公約数 g を決め打つ.
for (int g = 1; 2 * g <= a_max; g++) {
// (A[i], B[i]) を積 A[i] B[i] について昇順ソートする.
vector<tuple<long long, int, long long>> ab_a_b;
for (int a = g; a <= a_max; a += g) {
long long b = a_to_bmax[a];
if (b == -1) continue;
ab_a_b.emplace_back(a * b, a, b);
}
sort(ab_a_b.begin(), ab_a_b.end());
int K = (int)ab_a_b.size();
// A[i] の上からの累積最小値を求める.
vector<int> a_min(K + 1);
a_min[K] = a_max + 1;
for (int k = K - 1; k >= 0; k--) {
auto [ab, a, b] = ab_a_b[k];
a_min[k] = min(a_min[k + 1], a);
}
// 各 A[i] を採用する場合の調和度の最大値を求める.
for (int k = 0; k < K - 1; k++) {
auto [ab, a, b] = ab_a_b[k];
res = max(res, (b * g) / a_min[k + 1]);
}
}
cout << res << endl;
}