fzu1969 GCD Extreme 类似于uva10561

Description

Given the value of N, you will have to find the value of G. The meaning of G is given in the following code

 

G=0; 
for(i=1;i&ltN;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 20000 lines of inputs. Each line contains an integer N (1<N <1000001). 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

10 100 200000 0

Sample Output

67 13015 143295493160

Source

Contest for 2010 lecture II

 

题意:给出数字n,求对于所有满足1<= i < j <= n 的所有数对,(i,j)所对应的gcd(i,j)之和。

思路:设f(n) = gcd(1,n)+gcd(2,n)+gcd(3,n)+。。。+gcd(n-1,n)。则所求答案s(n)=f(2)+f(3)+f(4)+。。。+f(n)。

          注意到所有的gcd(x,n)的值都是n的约数,所以可以按照这个约数来进行分类。用g(n,i)来表示满足gcd(x,n)=i且x<n的正整数x的个数。则f(n)={i×g(n,i)|i为n的约数}。注意,g(n,i)=phi(n,i)。

         如果对于每个n都枚举i,按照数据范围来看肯定会超时,我们不如反着来,先枚举i,再找i的倍数n。这样时间复杂度会进一步减少。

 1 /*
 2  * Author:  Joshua
 3  * Created Time:  2014年09月07日 星期日 19时26分30秒
 4  * File Name: fzu1969.cpp
 5  */
 6 #include<cstdio>
 7 #include<cstring>
 8 typedef long long LL;
 9 #define maxn 1000005
10 int phi[maxn],a[maxn],f[maxn];
11 LL s[maxn];
12 bool p[maxn];
13 int tot=0;
14 
15 void pri()
16 {
17     memset(p,1,sizeof(p));
18     for (int i=2;i<maxn;++i)
19         if (p[i])
20         {
21             for (int j=i<<1;j<maxn;j+=i)
22                 p[j]=false;
23         }
24     for (int i=2;i<maxn;++i)
25         if (p[i]) a[++tot]=i;
26 }
27 
28 void phi_table()
29 {
30     for (int i=2;i<maxn;++i)
31     {
32         phi[i]=i;
33         int temp=i;
34         for (int j=1;j<=tot;++j)
35         {
36             if (temp==1) break; 
37             if (p[temp]) 
38             {
39                 phi[i]/=temp;
40                 phi[i]*=temp-1;
41                 break;
42             }
43             if (temp % a[j] == 0) 
44             {
45                 phi[i]/=a[j];
46                 phi[i]*=a[j]-1;
47                 while (temp%a[j]==0) temp/=a[j];
48             }
49         }
50     }
51 }
52 
53 void solve()
54 {
55     pri();
56     phi_table();
57     for (int i=1;i<maxn;++i)
58         for (int j=i;j<maxn;j+=i)
59             f[j]+=i*phi[j/i];
60     for (int i=1;i<maxn;++i)
61         s[i]+=s[i-1]+f[i];
62 }
63 
64 int main()
65 {
66     int n;
67     solve();
68     while (scanf("%d",&n) && n)
69         printf("%lld\n",s[n]); 
70     return 0;
71 }

 

posted @ 2014-09-09 16:58  一个大叔  阅读(212)  评论(0编辑  收藏  举报