zoukankan      html  css  js  c++  java
  • 【POJ2478】Farey Seque

    题意:

      就是求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
    ",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
    ",h[n]);
    48     }
    49     return 0;
    50 }
    poj24778

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

    2016-02-04 16:42:48

  • 相关阅读:
    java反射系七之动态代理
    java反射系列六之调用属性与方法
    java反射系列五之获取类的完整结构
    java反射系列四之创建运行时类的对象
    java反射系列三之类加载器
    java反射系列二
    java反射系列一
    数据类型
    类的加载、连接和初始化
    算法
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5181893.html
Copyright © 2011-2022 走看看