51nod 1040 最大公约数之和(欧拉函数)

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

题意:

思路:
最大公约数肯定也是在1~n这个范围里的,所以可以枚举所以因子(也就是1~n),计算出每个因子出现的个数,这样就能很快的求得结果。

这里就要用到欧拉函数了,假设现在我们枚举的是i这个因子,那么i出现的次数就是phi(n/i),此时求得数都是与n/i互素的,最后乘以i之后与n的最大公约数就是i。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn=1000+5;
16 
17 int n;
18 
19 int euler_phi(int n)
20 {
21     int m=sqrt(n+0.5);
22     int ans=n;
23     for(int i=2;i<=m;i++)  if(n%i==0)
24     {
25         ans=ans/i*(i-1);
26         while(n%i==0)  n/=i;
27     }
28     if(n>1)  ans=ans/n*(n-1);
29     return ans;
30 }
31 
32 int main()
33 {
34     //freopen("in.txt","r",stdin);
35     while(~scanf("%d",&n))
36     {
37         ll sum=0;
38         for(int i=1;i*i<=n;i++)
39         {
40             if(n%i==0)
41             {
42                 sum+=euler_phi(n/i)*i;
43                 if(i!=n/i)
44                     sum+=euler_phi(i)*(n/i);
45             }
46         }
47         printf("%lld
",sum);
48     }
49     return 0;
50 }
原文地址:https://www.cnblogs.com/zyb993963526/p/7616750.html