代码改变世界

pku_2480.Longge's problem

2011-05-23 02:27  Min·zc  阅读(210)  评论(0编辑  收藏  举报
 1 /*
 2  *欧拉函数的使用
 3  *题意是求解小于等于x的所有数的与x的最大公约数的和
 4  *
 5  *一个非常好的解题报告
 6  *http://blog.csdn.net/shiren_Bod/archive/2010/08/09/5798970.aspx
 7  *
 8  */
 9 
10 #include <iostream>
11 #include <math.h>
12 #include <memory.h>
13 using namespace std;
14 int s[50005];
15 int prime[50005];//因为只需要遍历到sqrt(n)所以只需要求解出2^15飞左右的所有素数就可以
16 void set()//筛法求素数
17 {
18         memset(s,0,sizeof(s));
19         memset(prime,0,sizeof(prime));
20         for(int i=2;i<50005;i++)
21                 if(s[i]==0)
22                         for(int j=2;j*i<50005;j++)
23                                 s[i*j]=1;
24         prime[0]=1;//使用prime[0]来记录素数的个数
25         for(int i=2;i<51000;i++)
26                 if(s[i]==0)
27                 {
28                         prime[prime[0]++]=i;
29                         
30                 }
31 }
32 long long eular(long long n)//求解欧拉函数
33 {
34 
35         long long ret=1;
36         long long tem=n;
37         for(int j=1;j<prime[0]&&prime[j]*prime[j]<=tem;j++)//只寻找素数可以加快计算速度
38         {
39         //     cout<<j<<endl;
40                 if(tem%prime[j]!=0)
41                         continue;
42                 ret*=(prime[j]-1);
43                 tem/=prime[j];
44                 while(tem%prime[j]==0)
45                 {
46                         tem/=prime[j];
47                         ret*=prime[j];
48                 }
49 
50         }
51         if(tem>1)
52                 ret*=(tem-1);
53         return ret;
54 }
55 int main()
56 {
57         long long n;
58         set();
59         //cout<<prime[0]<<endl;
60         while(cin>>n)
61         {
62                 int top=(int)sqrt((double)n);
63                 long long ans=0;
64                 for(int i=1;i<=top;i++)
65                 {
66                         if(n%i==0)
67                         {
68                                 ans+=i*eular(n/i);
69                         //   cout<<ans<<endl;
70                                 if(n!=i*i)
71                                         ans+=(n/i)*eular(i);    
72                         }
73                 }
74                 cout<<ans<<endl;
75         }
76 }