[P1390] 公约数的和 - 莫比乌斯反演

Description

给定 \(n\),求 \(\sum_{i = 1}^n \sum_{j = i + 1}^n \gcd(i, j)\)

Solution

经过一波推导得到

\[\sum_{i = 1}^n \sum_{j = i + 1}^n \gcd(i, j)=\sum_{k=1}^n k \sum_{k|d} \mu(\frac d k) [\frac N d]^2 \]

暴力计算即可

#include 
using namespace std;

#define int long long
const int N = 2000005;
const int MAXN = 2000005;

bool isNotPrime[MAXN + 1];
int mu[MAXN + 1], phi[MAXN + 1], primes[MAXN + 1], cnt;
inline void euler() {
    isNotPrime[0] = isNotPrime[1] = true;
    mu[1] = 1;
    phi[1] = 1;
    for (int i = 2; i <= MAXN; i++) {
        if (!isNotPrime[i]) {
            primes[++cnt] = i;
            mu[i] = -1;
            phi[i] = i - 1;
        }
        for (int j = 1; j <= cnt; j++) {
            int t = i * primes[j];
            if (t > MAXN) break;
            isNotPrime[t] = true;
            if (i % primes[j] == 0) {
                mu[t] = 0;
                phi[t] = phi[i] * primes[j];
                break;
            } else {
                mu[t] = -mu[i];
                phi[t] = phi[i] * (primes[j] - 1);
            }
        }
    }
}

int n,c[N];

signed main() {
    euler();
    ios::sync_with_stdio(false);
    cin>>n;
    int ans=0;
    for(int k=1;k<=n;k++) {
        int tmp=0;
        for(int d=k;d<=n;d+=k) {
            tmp+=mu[d/k]*(n/d)*(n/d);
        }
        ans+=tmp*k;
    }
    for(int i=1;i<=n;i++) ans-=i;
    cout<

你可能感兴趣的:([P1390] 公约数的和 - 莫比乌斯反演)