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 }

 

你可能感兴趣的:(ext)