码迷,mamicode.com
首页 > 其他好文 > 详细

【poj2478】Farey Sequence

时间:2016-02-04 18:40:33      阅读:235      评论:0      收藏:0      [点我收藏+]

标签:

题意:

技术分享

  就是求2~n的所有欧拉函数值的和,这里就用到了快速求欧拉函数的方法。(不能暴力求了,不然必定TLE啊)

  说说欧拉筛法,感觉十分机智啊~~

     技术分享

对于上述代码的几个问题:

  1.问:为什么i%prime==0时break?

     答:欧拉筛法每次合成时都是用最小质因子合成的,如果我们在程序加一行记录,即可先行求出1~Maxn的最小质因子。这样避免不必要的重复,提高效率。

  2.为什么当i%prime[j]==0时,phi[i*prime[j]]=phi[i]*prime[j]? 否则,phi[i*prime[j]]=phi[i]*(prime[j]-1)?

    答:这是欧拉函数的几个性质哦,下面说说这个东西的证明。

 


  欧拉函数的几个性质:E(x)表示比x小的且与x互质的正整数的个数。

  1、*若p是素数,E(p)=p-1。

  2、*E(p^k)=p^k - p^k /p  =   p* p^(k-1)  - 1*  p^(k-1)  =   (p-1)*p^(k-1)

证明如下:

      技术分享

  最后一行有点难理解,解释一下:

    假设a和b并不互质,b是质数,a是b的倍数。gcd(a,b)=b。E(a)和E(b)中都有一项(b-1)*b^0->(b-1),我们E(ab)的算式中间就有一项(b-1)*b,而E(a)和E(b)相乘后会变成(b-1)^2,所以在E(a)*E(b)的同时还要乘上b/b-1才能是结果正确,那么E(a*b)=E(a)*E(b)*b/b-1。因为b是质数,所以E(b)=b-1,所以有E(a*b)=E(a)*b。


  因此,我们得到两个推论咯:

  1、  当n为奇数时,E(2n)=E(n)

  2、  当n是一个大于2的正整数时,E(n)是偶数

  目前还没有发现这两个推论的用处,可以先记一记。不过上述两个性质是很重要哒~~~

 

这题的代码如下:

技术分享
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<cmath>
 7 using namespace std;
 8 #define Maxn 1000000
 9 #define LL long long
10 
11 int phi[Maxn+10],prime[Maxn+10];
12 LL h[Maxn+10];
13 bool vis[Maxn+10];
14 
15 void ffind()
16 {
17     memset(vis,0,sizeof(vis));
18     int len=0;
19     for(int i=2;i<=Maxn;i++)
20     {
21         if(!vis[i]) prime[++len]=i,phi[i]=i-1;
22         for(int j=1;j<=len;j++)
23         {
24             if(i*prime[j]>Maxn) break;
25             vis[i*prime[j]]=1;
26             if(i%prime[j]==0)
27             {
28                 phi[i*prime[j]]=phi[i]*prime[j];
29                 break;
30             }
31             else phi[i*prime[j]]=phi[i]*(prime[j]-1);
32         }
33     }
34     h[1]=0;
35     for(int i=2;i<=Maxn;i++) h[i]=h[i-1]+phi[i];
36     //for(int i=2;i<=20;i++) printf("%d:%d\n",i,phi[i]);
37 }
38 
39 int main()
40 {
41     int n;
42     ffind();
43     while(1)
44     {
45         scanf("%d",&n);
46         if(n==0) break;
47         printf("%lld\n",h[n]);
48     }
49     return 0;
50 }
poj24778

 

  感觉这种题就是,看着别人的题解做,理解思路比打代码花的时间多了去了。数论一定要好好理解透彻啊~~

 

2016-02-04 16:42:48

【poj2478】Farey Sequence

标签:

原文地址:http://www.cnblogs.com/Konjakmoyu/p/5181893.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!