結果
| 問題 | No.2262 Fractions |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2023-03-11 13:13:09 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 297 ms / 2,000 ms |
| コード長 | 1,938 bytes |
| 記録 | |
| コンパイル時間 | 2,111 ms |
| コンパイル使用メモリ | 199,196 KB |
| 最終ジャッジ日時 | 2025-02-11 09:55:50 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 45 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
vll PR;
void mobius(vll& A) {
ll N = A.size();
for (auto p : PR) {
if(p>N)break;
for (ll i = (N - 1) / p; i >= 1; i--) {
A[p * i] -= A[i];
}
}
return;
}
ll gcd(ll a, ll b) {
if (b == 0)return a;
ll c = a;
while (a % b != 0) {
c = a % b;
a = b;
b = c;
}
return b;
}
ll b = (1ll << 42);
ll num(ll p, ll N) {//p/b以下分母がN以下の既約分数
ll S = 0;
vll F(N + 1, 0);
for (ll i = 1; i <= N; i++) {
F[i] += (p * i) / b;//分母がiで mid/N以下の(既約とは限らない)分数の個数
}
//for (ll i = 1; i <= N; i++)cout << F[i] << (i == N ? "\n" : " ");
mobius(F);
//for (ll i = 1; i <= N; i++)cout << F[i] << (i == N ? "\n" : " ");
for (ll i = 1; i <= N; i++)S += F[i];
return S;
}
int main() {
ll NINF = 3e5 + 1;
vector<bool> P(NINF, 1);
for (int i = 2; i < NINF; i++) {
if (P[i]) {
PR.push_back(i);
for (int j = 2 * i; j < NINF; j += i)P[j] = 0;
}
}
ll T;
cin >> T;
while (T--) {
ll N, K;
cin >> N >> K;
ll L = num(b, N) - 1;
bool INV = 0;
if (K == L + 1) {
cout << "1/1" << endl;
continue;
}
if (K > 2 * L + 1) {
cout << -1 << endl;
continue;
}
if (K > L + 1) {
INV = 1;
K = 2 * L - K + 2;
}
ll l = 0, r = b+1;
while (r - l > 1)(num((r + l) / 2, N) < K ? l : r) = (r + l) / 2;
vll F(N + 1, 0);
pair<ll, ll> P;
for (ll i = 1; i <= N; i++) {
ll a=(r*i)/b;
if(gcd(a,i)==1)if(a*b>=l*i)P={a,i};
}
if (INV)swap(P.first, P.second);
cout << P.first << "/" << P.second << endl;
}
}