Uva_11462 GCD - Extreme (II)
题意:
给定一个n, 求:GCD(1, 2) + GCD(1, 3) + GCD(2, 3) + …… + GCD(1, n) + GCD(2, n) + …… + GCD(n-1, n);
设f(n) = ΣGCD(i, n), i = 1, 2, 3, ... , n-1
本题即求:f(2) + f(3) + f(4) + ... + f(n)
设s(n) = f(2) + f(3) + f(4) + ... + f(n)
1)
令 d = GCD(x, n), d 是 x, n的约数
所以, 1 = GCD(x/d, n/d) 所有满足条件的 x/d 的个数 则为 n/d的 欧拉函数值phi(n/d);
即满足d = GCD(x, n) 的x的个数为phi(n/d) , 这部分的和为phi(n/d) * d;
得, f(n) = Σ (i * phi(n/i)) i = [1, n-1]区间内n的所有约数。
2)
得出f(n) 的值, 我们就可以递推出s(n)的值了, s(n) = s(n-1) + f(n) , n >= 3
代码如下:
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <ctime> 6 #include <set> 7 #include <map> 8 #include <list> 9 #include <queue> 10 #include <string> 11 #include <vector> 12 #include <fstream> 13 #include <iterator> 14 #include <iostream> 15 using namespace std; 16 #define LL long long 17 #define MAXN 4000010 18 #define MOD 1000000007 19 #define eps 1e-6 20 int n; 21 LL f[MAXN], s[MAXN]; 22 int phi[MAXN]; 23 int euler_phi(int n) 24 { 25 int m = (int)sqrt(n + 0.5); 26 int ans = n; 27 for(int i = 2; i <= m; i ++) 28 if(n % i == 0) 29 { 30 ans = ans / i * (i - 1); 31 while(n % i == 0) n /= i; 32 } 33 if(n > 1) ans = ans / n * (n - 1); 34 return ans; 35 } 36 37 void phi_table(int n) 38 { 39 for(int i = 0; i <= n; i ++) phi[i] = 0; 40 phi[1] = 1; 41 for(int i = 2; i <= n; i ++) 42 if(!phi[i]) 43 { 44 for(int j = i; j <= n; j += i) 45 { 46 if(!phi[j]) phi[j] = j; 47 phi[j] = phi[j] / i * (i - 1); 48 } 49 } 50 } 51 void init() 52 { 53 for(int i = 1; i < MAXN; i ++) 54 for(int j = 2 * i; j < MAXN; j += i) 55 f[j] += i * phi[j/i]; 56 s[2] = f[2]; 57 for(int i = 3; i < MAXN; i ++) 58 s[i] = s[i-1] + f[i]; 59 } 60 61 int main() 62 { 63 phi_table(MAXN - 5); 64 init(); 65 while(scanf("%d", &n) && n) 66 { 67 printf("%lld\n", s[n]); 68 } 69 return 0; 70 }
【版权声明】
本博客版权归作者和博客园共有,作品来自于长沙.NET技术社区成员【吴俊毅】,有兴趣了解长沙.NET技术社区详情,请关注公众号【DotNET技术圈】