QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#93606#5503. Euclidean AlgorithmHCPS42#ML 0ms0kbC++173.5kb2023-04-01 21:11:572023-04-01 21:11:59

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-01 21:11:59]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2023-04-01 21:11:57]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

typedef long long LL;

ll my_sqrt(ll x) {
    ll res = sqrtl(x);
    while (res > 0 && LL(res) * res > x) {
        res--;
    }
    while (LL(res + 1) * (res + 1) <= x) {
        res++;
    }
    return res;
}

ll slow(ll n) {
    ll ans = 0;
    for (ll x = 1; x <= n; x++) {
        for (ll k = 2; k <= n; k++) {
            ans += (n / x - 1) / (k - 1);
        }
    }
    return ans;
}

const int N = 1e6 + 10;
ll mem[N];

void init() {
    for (int k = 1; k <= N - 1; k++) {
        for (int x = k; x <= N - 1; x += k) {
            mem[x] += x / k;
            if (x + k <= N - 1) {
                mem[x + k] -= x / k;
            }
        }
    }
    for (int i = 1; i <= N - 1; i++) {
        mem[i] += mem[i - 1];
    }
}

ll solve(ll n) {
    ll ans = 0;
    ll sqrt_1 = my_sqrt(n);
    for (ll x = 1; x <= sqrt_1; x++) {
        ll sqrt_2 = my_sqrt(n / x - 1);
        for (ll k = 2; k <= sqrt_2 + 1; k++) {
            ans += (n / x - 1) / (k - 1);
            // cout << x << " : " << k << "\n";
        }
        for (ll dk = 1; dk <= sqrt_2; dk++) {
            ll lk = (n / x + dk) / (dk + 1) + 1;
            ll rk = (n / x - 1) / dk + 1;
            lk = max(lk, sqrt_2 + 2);
            if (lk <= rk) {
                // cout << x << " : " << lk << " " << rk << " | " << dk << "\n";
                ans += dk * (rk - lk + 1);
            } else {
                break;
            }
        }
    }
    for (ll dx = 1; dx <= sqrt_1; dx++) {

        ll lx = (n + 1 + dx) / (dx + 1);
        ll rx = n / dx;
        lx = max(lx, sqrt_1 + 1);
        if (lx > rx) {
            break;
        }
        ans += mem[dx - 1] * (rx - lx + 1);
        /*
        ll sqrt_2 = my_sqrt(dx - 1);
        for (ll k = 2; k <= sqrt_2 + 1; k++) {
            ans += (dx - 1) / (k - 1) * (rx - lx + 1);
            // cout << lx << " " << rx << " : " << k << "\n";
        }
        for (ll dk = 1; dk <= sqrt_2; dk++) {
            ll lk = (dx + dk) / (dk + 1) + 1;
            ll rk = (dx - 1) / dk + 1;
            lk = max(lk, sqrt_2 + 2);
            if (lk <= rk) {
                // cout << lx << " " << rx << " : " << lk << " " << rk << "\n";
                ans += dk * (rk - lk + 1) * (rx - lx + 1);
            } else {
                break;
            }
        }
         */
    }
    return ans;
}

ll solve2(ll n) {
    ll ans = 0;
    for (ll lx = 1, rx; lx <= n; lx = rx + 1) {
        ll dx = n / lx;
        rx = n / dx;
        if (dx == 1) {
            continue;
        }
        for (ll lk = 1, rk; lk <= dx - 1; lk = rk + 1) {
            ll dk = (dx - 1) / lk;
            rk = (dx - 1) / dk;
            ans += dk * (rx - lx + 1) * (rk - lk + 1);
        }
    }
    return ans;
}

void stress() {
    for (int n = 1; n <= 1000; n++) {
        if (solve(n) != slow(n)) {
            cout << n << "\n";
        }
    }
    exit(0);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
#endif

    init();

    // stress();

    for (int i = 1; i <= 1; i++) {
        // cout << solve(1000000000ll) << "\n";
    }

    int t;
    cin >> t;
    while (t--) {
        ll n;
        cin >> n;
        cout << solve(n) << "\n";
    }

#ifdef LOCAL
    cout << "\nTime elapsed: " << double(clock()) / CLOCKS_PER_SEC << " s.\n";
#endif
}

详细

Test #1:

score: 0
Memory Limit Exceeded

input:

3
2
5
14

output:


result: