• 线性筛prime,强大O(n)


    和朴素的素数筛法一样,flag数组,记录x是否为素数

    flag[x]=0,x为合数

    falg[x]=1,x为素数

    flag[1],无定义

    其核心思想是,用x筛除与之差异最小的y,达到时间上O(n)的目的

    何为差异最小,呢?

    基于唯一分解定理,我们认为,x的素数分解集合(是可重集)

    大小记为|x|,如果|x|+1=|y|,我们则认为x,y差异最小

    即此时用x筛去y

    更重要的一点:

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

    什么意思呢?

    可以这样理解,此时的break是为了下一次筛(暂时的失败是为了下一次更好的成功)

    应为,能被i筛去的,一定能被p[j]筛去,p[j]后面的下一次反正会用到

    所以让p[j]和它后面的素数去筛就好了

    举一个栗子:

    用2,3我们可以筛去4,6,9

    像这样:

       1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17

    a[0  0  0  1  0  1  0  0  1  0   0   0   0   0   0   0   0 ]

    但是

    4,只会筛去8,而没有12

    因为,12是留给6筛的,所以代码就很简单了

     1 typedef long long ll;
     2 const int MAXP=50000+10;
     3 ll p[MAXP],flag[MAXP],cnt;
     4 void prime(int n){
     5   for(int i=2;i<=n;i++){
     6     if(!flag[i])p[++cnt]=i;
     7     for(int j=1;j<=cnt && i*p[j]<=n;j++){
     8       flag[i*p[j]]=1;
     9       if(i%p[j]==0)break;
    10     }
    11   }
    12 }
    13 int main(){
    14   prime(100);
    15   for(int i=1;i<=cnt;i++)printf("p[%d]=%lld\n",i,p[i]);
    16   return 0;
    17 }
    prime(100)
    ~~Jason_liu O(∩_∩)O
  • 相关阅读:
    产品 | What's产品经理
    产品 | 互联网+“加油”
    微信小程序 | 未来O2O电商的“阴谋”
    推荐书籍 | 产品必备书籍
    iOS | NSProxy
    iOS | 解决中文乱码
    HTML DOM addEventListener() 方法
    给每个对象加上新的属性
    vue.config.js基础配置
    SEO要点
  • 原文地址:https://www.cnblogs.com/JasonCow/p/6534810.html
Copyright © 2020-2023  润新知