hdu 2824 The Euler function

欧拉函数~~

第一次写欧拉函数,以前只知道其定义,以为编码按其过程一步一步的实现应该就可以,结果发现不太一样。

超时的想法:首先筛选素数,刚开始是筛选了N以内的所有素数,然后对于每个数,从小到大枚举素数,

for(;;)//枚举素数

if(n%prime[i]==0)

{

   phj[n]=phj[n]-phj[n]/prime[i];

   while(n%prime[i]==0)

   {

        n/=prime[i];

    }

}

超时了之后,发现素数其实没必要枚举到N,只用枚举到sqrt(N)

因为对于每一个数n,for()循环之后,如果n不为1,那n肯定是一个大于sqrt(N)的素数。

但是这样之后还是超时了。。

之后看了百科上面的算法,他是对每一个素数,枚举他的倍数,这样每一步都是有效的,效率就提高了。

View Code
 1 # include<stdio.h>

 2 # include<string.h>

 3 # include<stdlib.h>

 4 # define N 3000005

 5 bool vis[N];

 6 int phj[N];

 7 //__int64 sum[N];

 8 int main()

 9 {

10     int i,j,a,b;

11     __int64 ans;

12     memset(vis,0,sizeof(vis));

13     for(i=2;i*i<3000000;i++)

14     {

15         if(vis[i]) continue;

16         for(j=i+i;j<3000000;j+=i)

17             vis[j]=1;

18     }

19     for(i=3;i<3000000;i++)

20         phj[i]=i;

21     for(i=2;i<3000000;i++)

22     {

23         if(vis[i]==0)

24         {

25             for(j=i;j<3000000;j+=i)

26                 phj[j]=phj[j]-phj[j]/i;

27         }

28     }

29     /*sum[2]=0;

30     for(i=3;i<=3000000;i++)

31         sum[i]=sum[i-1]+phj[i];*/

32     while(scanf("%d%d",&a,&b)!=EOF)

33     {

34         ans=0;

35         for(i=a;i<=b;i++)

36             ans+=phj[i];

37         printf("%I64d\n",ans);

38         //printf("%I64d\n",sum[b]-sum[a-1]);

39     }

40     return 0;

41 }

 

 

 

你可能感兴趣的:(function)