UVa 11426

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2421

代码及其注释:

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>

#define ll long long
#define lint long long
using namespace std;

const int N=4000005;
int phi[N];//phi[k] 表示从1到k 和k互质的数有几个
ll f[N],sum[N];//f[k] 表示从1到k-1 依次求和k的最大公约数 所以最大公约数的总和
void phin(int n=N-1)
{
    memset(phi,0,sizeof(phi));
    phi[1]=1;
    for(int i=2;i<=n;++i)
    if(!phi[i])
    {
        for(int j=i;j<=n;j=j+i)
        {
            if(!phi[j]) phi[j]=j;
            phi[j]=phi[j]/i*(i-1);
        }
    }
}
int main()
{
    //freopen("data.in","r",stdin);
    phin();
    memset(f,0,sizeof(f));
    memset(sum,0,sizeof(sum));
    for(int i=1;i<N;++i)
    for(int j=i+i,l=2;j<N;j=j+i,++l)
    {
        f[j]+=(ll)phi[l]*(ll)i;//这里的phi[l]表示小于j的数中与j的最大公约数是i的数的个数
    }
    for(int i=1;i<N;++i)
    sum[i]=f[i]+sum[i-1];
    int k;
    while(cin>>k)
    {
        if(!k) break;
        cout<<sum[k]<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/liulangye/p/3177392.html