zoukankan      html  css  js  c++  java
  • 康复计划之线性筛

    假如我给你一个n,让你输出n以内所有的素数,你会怎么做?

    最好想的做法是一个一个枚举,然后检验,复杂度O(n*√n)

    那有没有更优的做法呢?

    理论上最低复杂度是n,那么能达到吗?

    我们看下面一段代码:

     1 inline void pre_() {
     2     for(int i=2;i<=n;i++) pp[i] = 1 ; pp[1] = 0 ;   // pp为bool型数组,记录数字i是否为素数,筛之前我们默认2以后都为素数
     3     for(int i=2;i<=n;i++) {
     4         if(pp[i]) prime[++tot] = i ;                 // 如果一个数是素数,就把他放到prime数组中
     5         for(int j=1;j<=tot&&prime[j]*i<=n;j++) {          
     6             pp[i*prime[j]] = 0 ;                      // 筛
     7             if(!(i%prime[j])) break ;                // 优化 达到线性目的的关键
     8         }
     9     }
    10 }

    为什么它是线性的呢?

    我们只需要证明两点:

    1,每个合数都会被筛掉

    2,每个被筛掉的合数只会被筛一次

    我们把每个合数分解为a1*a2*...*an的形式。(其中a1-an都是素数,a1<a2<...<an

    对于1:当i为a2*a3*...*an时,prime[j]为a1时,该数一定会被筛掉

    对于2:当prime[j]=ax(x!=1), i=a1*...*ax-1*ax+1*...*an时,由于当prime[j]=a1时就会从循环中break出来,而a1 < ax, 所以无法令j满足prime[j]=ax,所以一个数不存在其他被筛的机会。

    得证

    于是我们就有了一个理论最低复杂度的筛素数方法啦!

  • 相关阅读:
    钉钉 LDAP
    OpenLDAP 密码策略与审计控制
    Active Directory LDAP DingDing
    Linux kill 命令 java
    Memory Analyzer 与 Java VM 版本支持问题
    java.lang.Thread.State
    稻盛和夫 活法 人生公式
    [领导力/管理]一句话说带团队
    把某个公司git项目迁移到gitee的步骤
    Protocol Buffers  |  Google Developers
  • 原文地址:https://www.cnblogs.com/zub23333/p/11495648.html
Copyright © 2011-2022 走看看