1. 程式人生 > >51nod 1040 最大公約數之和(歐拉函數)

51nod 1040 最大公約數之和(歐拉函數)

wid con cst 都是 快的 .html lan inf log

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\n",sum); 48 } 49 return 0; 50 }

51nod 1040 最大公約數之和(歐拉函數)