結果

問題 No.2849 Birthday Donuts
ユーザー AngrySadEight
提出日時 2024-06-09 01:53:21
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
RE  
(最新)
AC  
(最初)
実行時間 -
コード長 2,098 bytes
コンパイル時間 686 ms
コンパイル使用メモリ 76,628 KB
最終ジャッジ日時 2025-02-21 21:01:36
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample RE * 1
other AC * 1 WA * 1 RE * 19
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
using ll = long long;

ll my_gcd(ll a, ll b) {
    ll ret = 0;
    if (a < b) {
        swap(a, b);
    }
    if (b == 0) {
        ret = a;
    } else {
        ret = my_gcd(b, a % b);
    }
    return ret;
}

int main() {
    vector<ll> divisor(300002, -1);
    for (ll i = 2; i <= 300000; i++) {
        for (ll j = 2; j * i <= 300000; j++) {
            divisor[j * i] = j;
        }
    }
    vector<ll> phi(300002, 0);
    for (ll i = 2; i <= 300000; i++) {
        ll now = i;
        ll div = -1;
        ll tot = i;
        while (true) {
            if (divisor[now] == -1) {
                if (now != div) {
                    tot = tot * (now - 1);
                    tot /= now;
                }
                break;
            }
            if (div != divisor[now]) {
                div = divisor[now];
                tot = tot * (div - 1);
                tot /= div;
            }
            now /= div;
        }
        phi[i] = tot;
    }
    vector<ll> phi_sum(300002, 0);
    for (ll i = 2; i <= 300000; i++) {
        phi_sum[i] = phi_sum[i - 1] + phi[i];
    }
    ll T;
    cin >> T;
    while (T--) {
        ll L, R;
        cin >> L >> R;
        ll ans = 0;
        for (ll i = 2; i <= 500; i++) {
            ll k1 = (L - 1) / i;
            ll k2 = R / i;
            if (k1 < k2) {
                ans += phi[i];
            }
        }
        ll left = 0;
        ll right = 1;
        ll prev = R;
        while (true) {
            if (R < 500) {
                break;
            }
            ll nl = (L - 1) / (left + 1);
            ll nr = R / (right + 1);

            ll val = max(nl, nr);
            if (left != right) {
                ans += (phi_sum[prev] - phi_sum[max(val, 500LL)]);
            }
            if (val <= 500) {
                break;
            }
            prev = val;
            if (nl >= nr) {
                left++;
            } else {
                right++;
            }
        }
        cout << ans << endl;
    }
}
0