zoukankan      html  css  js  c++  java
  • 线性筛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
  • 相关阅读:
    前沿技术解密——VirtualDOM
    Ques核心思想——CSS Namespace
    Unix Pipes to Javascript Pipes
    Road to the future——伪MVVM库Q.js
    聊聊CSS postproccessors
    【译】十款性能最佳的压缩算法
    Kafka Streams开发入门(9)
    Kafka Streams开发入门(8)
    【译】Kafka Producer Sticky Partitioner
    【译】99th Percentile Latency at Scale with Apache Kafka
  • 原文地址:https://www.cnblogs.com/JasonCow/p/6534810.html
Copyright © 2011-2022 走看看