[uva 11426] GCD - Extreme (II)

A - GCD - Extreme (II)
 

Description

Given the value of N, you will have to find the value of G. The definition of G is given below:

Here GCD(i,j) means the greatest common divisor of integer i and integer j.

For those who have trouble understanding summation notation, the meaning of G is given in the following code: 

G=0;



for(i=1;i<N;i++)



for(j=i+1;j<=N;j++)



{



    G+=gcd(i,j);



}



/*Here gcd() is a function that finds the greatest common divisor of the two input numbers*/
Input

The input file contains at most 100 lines of inputs. Each line contains an integer N (1<N<4000001). The meaning of N is given in the problem statement. Input is terminated by a line containing a single zero. 

Output

For each line of input produce one line of output. This line contains the value of G for the corresponding N. The value of G will fit in a 64-bit signed integer.

Sample

10            67

100          13015

200000     153295493160

0

 

枚举最大公约数、利用欧拉函数

#include <iostream>

#include <cstdio>

#include <cstring>

using namespace std;

#define ll long long

#define N 4000000



int tot;

int prime[N+10];

bool isprime[N+10];

int phi[N+10];

void prime_pri()

{

    tot=0;

    phi[1]=1;

    memset(isprime,1,sizeof(isprime));

    isprime[0]=isprime[1]=false;

    for(int i=2;i<=N;i++)

    {

        if(isprime[i])

        {

            prime[tot++]=i;

            phi[i]=i-1;

        }

        for(int j=0;j<tot;j++)

        {

            if((ll)i*prime[j]>N) break;

            isprime[i*prime[j]]=0;

            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 n;

ll tmp[N+10];

ll ans[N+10];

int main()

{

    prime_pri();

    for(int i=1;i<=N;i++) //枚举gcd

    {

        for(int j=i+i;j<=N;j+=i)

        {

            tmp[j]+=(ll)phi[j/i]*i;

        }

    }

    for(int i=2;i<=N;i++) ans[i]=ans[i-1]+tmp[i];

    while(scanf("%d",&n),n)

    {

        printf("%lld\n",ans[n]);

    }

    return 0;

}

 

你可能感兴趣的:(ext)