神奇的线性筛法

关于线筛

所谓线性筛法,顾名思义它是线性的筛素数的方法,所以是 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] 筛到
所以后面的都不必筛了。

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值