zoukankan      html  css  js  c++  java
  • 【转】欧拉筛

    原博是这个链接:    线性筛(欧拉筛)  http://www.cnblogs.com/zhuohan123/p/3233011.html

    我只拷贝了我在学的内容——

    一般的筛法(PPT里叫埃拉托斯特尼筛法,名字异常高贵)的效率是O(NlglgN)(其实很接近O(n)啊!),对于一些例如N=10000000的残暴数据会跪,于是,线性筛登场了…

     1 #include <cstring>
     2 using namespace std;
     3 int prime[1100000],primesize,phi[11000000];
     4 bool isprime[11000000];
     5 void getlist(int listsize)
     6 {
     7     memset(isprime,1,sizeof(isprime));
     8     isprime[1]=false;
     9     for(int i=2;i<=listsize;i++)
    10     {
    11         if(isprime[i])prime[++primesize]=i;
    12          for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++)
    13          {
    14             isprime[i*prime[j]]=false;
    15             if(i%prime[j]==0)break;
    16         }
    17     }
    18 }

    以上是线性筛代码。

    就我的理解,线性筛有两个地方与一般筛不同:

    1.两层循环的顺序不同(一般筛是第一维prime[i] 第二维j,欧拉筛是第一维i 第二位prime[j])

    2.一行神奇的代码:

    14             if(i%prime[j]==0)break;

    这行代码神奇地保证了每个合数只会被它的最小素因子筛掉,就把复杂度降到了O(N)。

    接下来是证明这个算法正确性的说明:

         prime[]数组中的素数是递增的,当i能整除prime[j],那么i*prime[j+1]这个合数肯定被prime[j]乘以某个数筛掉。因为i中含有prime[j],prime[j]比prime[j+1]小,即i=k*prime[j],那么i*prime[j+1]=(k*prime[j])*prime[j+1]=k’*prime[j],接下去的素数同理。所以不用筛下去了。因此,在满足i%prime[j]==0这个条件之前以及第一次满足改条件时,prime[j]必定是prime[j]*i的最小因子。

          显然,线性筛只拿来筛筛素数是很不科学的,它的速度大约是一般筛的3~4倍,在数据量小的时候甚至慢些(用到了mod运算)。它的重量级应用是——求解积性函数。

  • 相关阅读:
    Notes相关开发Tips
    gridView滚动条相关问题
    MyBatis学习(一)简单入门程序
    springMVC入门
    zoj 3702 Gibonacci number 找规律
    邻接表表示
    poj 1269 直线相交情况
    poj 3304 Segments 线段与直线相交的判断
    poj 1654 多边形面积
    zoj 3696 Alien's Organ 概率,泊松分布
  • 原文地址:https://www.cnblogs.com/konjak/p/6061955.html
Copyright © 2011-2022 走看看