51nod 1040 欧拉函数

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040

1040 最大公约数之和

题目来源: rihkddd
基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
收藏
关注
给出一个n,求1-n这n个数,同n的最大公约数的和。比如:n = 6
1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15
Input
1个数N(N <= 10^9)
Output
公约数之和
Input示例
6
Output示例
15

ans=SUM{gcd(x,n) | x>=1&&x<=n }
注意到gcd(x,n)一定是n的约数,我们令g(n,i)表示gcd(x,n)==i的x的个数,这样ans=SUM{i*g(n,i) | n%i==0 }
由gcd(x,n)==i ==> gcd(x/i,n/i)==1,所以转化为求满足gcd(x/i,n/i)==1的x/i的个数,显然x/i<=n/i,二者互素,答案就是phi(n/i);
只要枚举出所有的因子就好了计算phi就好了。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 using namespace std;
 6 #define LL long long 
 7  
 8 LL Euler(LL n)
 9 {
10     LL i, temp = n;
11     for (i = 2;i*i <= n;i++)
12         if (n%i == 0)
13         {
14             while (n%i == 0)
15                 n = n / i;
16             temp = temp / i*(i - 1);
17         }
18     if (n != 1)
19         temp = temp / n*(n - 1);
20     return temp;
21 }
22  
23 int main()
24 {
25     LL n, i, sum, k;
26     while (scanf("%lld",&n)!=EOF)
27     {
28         sum = 0;
29         for (i = 1;i*i <= n;i++)
30         {
31             if (n%i == 0)
32                 sum = sum + Euler(n / i)*i;
33             k = n / i;
34             if (n%k == 0 && k != i)
35                 sum = sum + Euler(n / k)*k;
36         }
37         printf("%lld\n", sum);
38     }
39     return 0;
40 }

 

posted @ 2017-08-28 16:55  *zzq  阅读(195)  评论(0)    收藏  举报