神奇的线性筛法

原创 2016年06月01日 21:19:58

关于线筛

所谓线性筛法,顾名思义它是线性的筛素数的方法,所以是O(N)

神奇的东西

int getprime(int lim)
{
    int i,j,num=0;
    fo(i,2,lim) 
    {
        if (!bz[i])
        {
            prime[++num]=i;
            for(j=1;i*j<=lim;j++) bz[i*prime[j]]=1;
        }   
    }
}

这是普通筛法

int getprime(int lim)
{
    int i,j,num=0;
    fo(i,2,lim) 
    {
        if (!bz[i]) prime[++num]=i;
        for(j=1;i*prime[j]<=lim&&j<=num;j++)
        {
            bz[i*prime[j]]=1;
            if (!(i%prime[j])) break;
        } 
    }
}

这是线性筛法

实测

某神犇已经测过,我直接上结果

  • 筛 [0, 100000) 范围内的素数
    第一种素数筛法 0 毫秒
    第二种素数筛法 0 毫秒

  • 筛 [0, 200000) 范围内的素数
    第一种素数筛法 15 毫秒
    第二种素数筛法 0 毫秒

  • 筛 [0, 400000) 范围内的素数
    第一种素数筛法 16 毫秒
    第二种素数筛法 15 毫秒

  • 筛 [0, 800000) 范围内的素数
    第一种素数筛法 47 毫秒
    第二种素数筛法 16 毫秒

  • 筛 [0, 1600000) 范围内的素数
    第一种素数筛法 62 毫秒
    第二种素数筛法 63 毫秒

  • 筛 [0, 3200000) 范围内的素数
    第一种素数筛法 297 毫秒
    第二种素数筛法 109 毫秒

  • 筛 [0, 6400000) 范围内的素数
    第一种素数筛法 922 毫秒
    第二种素数筛法 266 毫秒

  • 筛 [0, 12800000) 范围内的素数
    第一种素数筛法 2187 毫秒
    第二种素数筛法 563 毫秒

  • 筛 [0, 25600000) 范围内的素数
    第一种素数筛法 4828 毫秒
    第二种素数筛法 1187 毫秒

为什么是线性的呢?

回到程序

可以发现,普通筛法将每个质数的倍数都筛掉,每个合数都被筛了它的质因子次
That’s too slow!!

我们再看线性筛法
筛的时候,把当前到的这一个数(不论质数合数)乘上筛出来的每个质数筛一遍

关键是这一句

if (!(i%prime[j])) break;

这样的情况,意思是prime[j]这一个质数在prime[j]×i中指数已经大于等于2了。

并且,这个合数的任何倍数以后一定会被prime[j]筛到
所以后面的都不必筛了。

这样,每个合数都只被它的最小的质因子筛过一遍,所以是线性的复杂度。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

线性筛法及扩展

以下代码中的定义: mindiv[i]:i的最小质因子 phi[i]:欧拉函数i的值 mindivq[i]:i的最小质因子的个数 d[i]:i的约数个数 sumd[i]:i的约数和 miu...
  • D042412
  • D042412
  • 2015年07月17日 20:44
  • 1311

欧拉函数线性筛法详解

该算法在可在线性时间内筛素数的同时求出所有数的欧拉函数。
  • Lytning
  • Lytning
  • 2014年04月24日 19:52
  • 5142

当我真正理解素数线性筛法

参考自:点击链接 主要代码:const int MAXN = 10000010; bool com[MAXN]; int primes, prime[MAXN/10];//数组不必开的太大 ...

线性筛法

又重新统一了下线性筛法模版 void linear_prime(int wt)//线性筛法筛质数 {    for(int i = 2; i ...

线性筛法求解 H数列问题

Description 有一组数列,1, 5, 9, 13, 17, 21,25...,(都模4余1),叫做H数列。 可以把H数列中的数分为三种 (1)H-素数:h是H-素数,把h是分解成两...
  • ljd4305
  • ljd4305
  • 2012年08月25日 11:17
  • 1405

线性筛法 gcd 快速幂

线性筛法、gcd、快速幂[介绍]今天特地学了下线筛,感觉棒棒哒。。。线性筛法,顾名思义,就是每个数筛一遍,即每个合数只标记一次,我们知道,一个合数可以写成一个素数和一个数的乘积的形式,而要想每个数筛一...
  • Yancy_
  • Yancy_
  • 2017年01月31日 22:25
  • 209

线性筛法相关

基本证明可以看这里,懒得多写。 一个藓的证明其实还可以筛其他东西,先看一个筛出约数个数的 dhdh写的 他有个地方写错了,a mod b≠0不代表ab互质…. 首先吧,肯定要维护这个玩意Ansi...

【BZOJ 2818】 gcd(附φ的线性筛法预处理)

Description 给定整数N,求1

线性筛法(欧拉筛)

从前有一个素数筛法叫埃拉托斯特尼筛法,它的思想很简单,把1-n以内素数的整数倍的数字划掉,留下的就全是素数,但是它的复杂度是O(NlglgN),对于大量不友好数据会跪,于是线性晒登场了。 #inclu...
  • zjq_01
  • zjq_01
  • 2017年06月02日 19:30
  • 155

素数筛法 埃氏筛 线性筛

素数筛法? 呃~,太暴力的试1~sqrt(n)时候是因数就不说了。 这里介绍埃氏筛和线性筛。埃氏筛埃氏筛主要原理是: 每次搜索到一个质数将他的倍数标记为合数; 本质原理就是:一个合数一定表示为...
  • sdfzsyh
  • sdfzsyh
  • 2017年07月06日 22:10
  • 188
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:神奇的线性筛法
举报原因:
原因补充:

(最多只允许输入30个字)