UVA 11426 GCD - Extreme (II) (欧拉函数)

转载请注明出处: http://www.cnblogs.com/fraud/           ——by fraud

Problem J
GCD Extreme (II)
Input: Standard Input

Output: Standard Output

 

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 Input     Output for Sample Input

10

100

200000

0

 

67

13015

143295493160

 


Problemsetter: Shahriar Manzoor

Special Thanks: SyedMonowarHossain

设dp[i]=gcd(1,i)+gcd(2,i)+……+gcd(i-1,i);

则ans[n]=dp[2]+dp[3]+……+dp[n].

由此问题已经转化成如何求dp[i]了,即需要求1到i-1所有数与i的gcd的和。

设k为满足gcd(x,i)=j且x<i的正整数的个数,则dp[i]=∑j*k;

同时,由于gcd(x,i)=j等价于gcd(x/j,i/j)=1,也就是phi[i/j];

接下来反过来求,那就不需要分解素因子了

 1 #include <iostream>

 2 #include <cstring>

 3 using namespace std;

 4 typedef long long ll;

 5 const int maxn=4000010;

 6 int phi[maxn];

 7 ll dp[maxn+1];

 8 ll ans[maxn+1];

 9 void phi_table()

10 {

11     phi[1]=1;

12     for(int i=2;i<maxn;i++)

13     {

14         if(!phi[i])

15         {

16             for(int j=i;j<maxn;j+=i)

17             {

18                 if(!phi[j])phi[j]=j;

19                 phi[j]=phi[j]/i*(i-1);

20             }

21         }

22     }

23 }

24 int main()

25 {

26     ios::sync_with_stdio(false);

27     phi_table();

28     for(int i=1;i<maxn;i++)

29     {

30         for(int j=i*2;j<maxn;j+=i)dp[j]+=(long long)i*(long long)phi[j/i];

31     }

32     ans[2]=dp[2];

33     for(int i=3;i<maxn;i++)ans[i]=ans[i-1]+dp[i];

34     int n;

35     while(cin>>n&&n)

36     {

37         cout<<ans[n]<<endl;

38     }

39     return 0;

40 }
View Code

 

你可能感兴趣的:(ext)