http://www.51nod.com/onlineJudge/questionCode.html#!problemId=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 ", sum); 38 } 39 return 0; 40 }