UVa 11426 - GCD - Extreme (II)

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;

}

 

你可能感兴趣的:(ext)