UVA 11426 GCD - Extreme (II)

题目大意:

  求G的值,其中1<N<4000001;

解题思路:

  假设[1,n-1]中所有的数分别与n的gcd的和记为b[n],可以看出G[n] = G[n-1] + b[n],

这样就把题目转换为了求b[n]。

假设a[x]表示使gcs(n, b) = x成立的b有多少个,b[n] = a[x1]*x1 + a[x2]*x2 + ...... + a[xk]*xk。

我们只需要求a[n].

因为有gcd的性质:gcd(n, b) = x --> gcd(n/x, b/x) = 1;可以用欧拉函数求出a[n/xi]即可。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 
 8 #define maxn 4000005
 9 #define LL long long
10 LL a[maxn], b[maxn], dp[maxn];
11 
12 int main()
13 {
14     int n, i, j;
15     for (i=2; i<maxn; i++)
16         if (!a[i])
17             for (j=i; j<maxn; j+=i)
18             {
19                 if (!a[j])
20                     a[j] = j;
21                 a[j] = a[j] / i * (i-1);
22             }
23     //欧拉函数打表
24     for (i=1; i<maxn; i++)
25         for (j=i*2; j<maxn; j+=i)
26             b[j] += a[j/i]*i;
27     //[1,n-1]中所有的数与n的gcd的和
28     for (i=2; i<maxn; i++)
29         dp[i] = dp[i-1]+b[i];
30     //题目所问
31     while (scanf ("%d", &n), n)
32         printf ("%lld\n", dp[n]);
33     return 0;
34 }

 

posted @ 2015-04-27 10:14  罗茜  阅读(152)  评论(0编辑  收藏  举报