GCDSUM - Tổng các ước chung lớn nhất

Tác giả: RR

Ngôn ngữ: C++


#include <sstream>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <queue>
#include <bitset>
using namespace std;

#define int long long
#define FOR(i, a, b) for (int i = (a), _b = (b); i <= _b; ++i)
#define FORD(i, a, b) for (int i = (a), _b = (b); i >= _b; --i)
#define REP(i, a) for (int i = 0, _a = (a); i < _a; ++i)
#define REPD(i,n) for(int i = (n)-1; i >= 0; --i)

#define DEBUG(X) { cerr << #X << " = " << (X) << endl; }
#define PR(A, n) { cerr << #A << " = "; FOR(_, 1, n) cerr << A[_] << ' '; cerr << endl; }
#define PR0(A, n) { cerr << #A << " = "; REP(_, n) cerr << A[_] << ' '; cerr << endl; }

#define sqr(x) ((x) * (x))
#define ll long long
#define double long double
typedef pair<int, int> II;
#define PI (2 * acos((double)0))
#define __builtin_popcount __builtin_popcountll
#define SZ(x) ((int)(x).size())
#define ALL(a) (a).begin(), (a).end()
#define MS(a,x) memset(a, x, sizeof(a))
#define next ackjalscjaowjico
#define prev ajcsoua0wucckjsl
#define y1 alkscj9u20cjeijc
#define y0 u9cqu3jioajc

double safe_sqrt(double x) { return sqrt(max((double)0.0, x)); }
int GI(int& x) { return scanf("%lld", &x); }

const int MN = 1000111;
int phi[MN], f[MN];

void init() {
    int N = 1000 * 1000;
    
    // phi[i] = cnt(x: 1 <= x <= i && gcd(x, i) == 1)
    FOR(i,1,N) phi[i] = i;
    FOR(i,2,N)
        if (phi[i] == i)
            for(int j = i; j <= N; j += i)
                phi[j] -= phi[j] / i;

    // f[i] = cnt(x, y: 1 <= x, y <= i && gcd(x, y) == 1)
    f[1] = 0;
    FOR(i,2,N) f[i] = f[i-1] + phi[i];
}

int32_t main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout << (fixed) << setprecision(9);
    init();
    int n;
    while (GI(n) == 1 && n) {
        int s = 0;
        for(int i = 1; i <= n; ) {
            int q = n / i;
            int r = n / q;
            s += (r - i + 1) * (i + r) / 2 * f[q];
            i = r + 1;
        }

        cout << s << '\n';
    }
}

Download