GCD Extreme (II)
Given the value of N, you will have to find the value of G. The definition of G is given below:
uva 11426 - GCD - Extreme (II)" v:shapes="_x0000_i1025">
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<<span class="SpellE">N;i++) for(j=i+1;j<=N;j++) { G+=gcd(i,j); } |
Input
The input file contains at most 100 lines of inputs. Each line contains an integer N (1
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
Output for Sample Input
67
13015
143295493160
题意:
输入正整数n,求gcd(1,2)+gcd(1,3)+gcd(2,3)+…+gcd(n-1,n),即所有满足1<=i<j<=n的数对(i,j)所对应的gcd(i,j)之和。
分析:
设f(n) = gcd(1,n)+gcd(2,n)+…+gcd(n-1,n),则所求答案就是S(n)=f(2)+f(3)+…f(n)。
只要求出f(n),就可以得到答案S(n) = S(n-1)+f(n)。
注意到所有的gcd(x,n)都是n的约数,可以按照这个约数进行分类,用g(n,i)表示满足gcd(x,n)=i的不大于n的正整数x的个数,则f(n)=sum{i*g(n,i)|i是n的约数}。注意到gcd(x,n)=i的充要条件是gcd(x/I,n/i)=1,所以g(n,i)=phi(n/i)。
我们不需要对每一个n都枚举其约数i。可以反过来思考,对于每一个i,枚举其倍数n并更新f(n)的值那么时间复杂度将与筛法同阶。

1 #include <cstdio> 2 #include <cstring> 3 const int maxn = 4000000; 4 typedef long long LL; 5 LL S[maxn + 1],f[maxn + 1]; 6 int phi[maxn]; 7 void phi_table(int n){ 8 for(int i = 2 ; i <= n ; i++) phi[i] = 0; 9 phi[1] = 1; 10 for(int i = 2; i <= n ; i++) if(!phi[i]) 11 for(int j = i ; j <= n ; j += i){ 12 if(!phi[j]) phi[j] = j; 13 phi[j] = phi[j] / i * (i - 1); 14 } 15 } 16 int main(){ 17 phi_table(maxn); 18 // 预处理f 19 memset(f,0,sizeof f); 20 for(int i = 1 ; i <= maxn ; i++) 21 for(int n = i * 2 ; n <= maxn ; n += i) f[n] += i * phi[n / i]; 22 // 预处理S 23 S[2] = f[2]; 24 for(int n = 3 ; n <= maxn ; n++) S[n] = S[n - 1] + f[n]; 25 int n; 26 while(scanf("%d",&n) == 1 && n) 27 printf("%lld ",S[n]); 28 return 0; 29 }