UVA 11426 GCD

题目大意:

求出

我们可以通过求∑(1<=i<=N)∑(1<=j<=N)gcd(i,j) 然后减去 i , j相同的情况,最后因为 i , j 互换取了两次所以除以2

上述式子等于 ∑(1<=i<=N)∑(1<=j<=N)∑(d|gcd(i,j))phi[d]     phi[d]  是欧拉函数

∑phi[d]∑∑(1<=i<=N/d)∑(1<=j<=N/d)

#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;
#define ll long long
const int N = 4000010;
int prime[N] , phi[N] , tot;
bool vis[N];

void get_phi()
{
    memset(vis , 0 , sizeof(vis));
    tot = 0 , phi[1] = 1;
    for(int i=2 ; i<=4000000 ; i++){
        if(!vis[i]) prime[tot++] = i , phi[i] = i-1;
        for(int j=0 ; j<tot ; j++){
            if(i*prime[j]>4000000) break;
            vis[i*prime[j]]=true;
            if(i%prime[j] == 0){
                phi[i*prime[j]] = phi[i]*prime[j];
                break;
            }
            else phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
}

int main()
{
  //  freopen("a.in" , "r" , stdin);
    get_phi();
    int n;
    while(scanf("%d" , &n) , n)
    {
        ll ans = 0;
        for(int d=1 ; d<=n ; d++){
            ans = ans+(ll)(n/d)*(n/d)*phi[d];
            ans = ans - d;
        }
        printf("%lld
" , ans/2);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/CSU3901130321/p/4261004.html