快速线性筛

快速线性筛可以使我们能够在线性时间内筛出特定区间内的素数。
代码的基本思路是,开两个数组num[x]prime[x],其中前者记录\(x\)是否为素数,后者记录第\(x\)个素数。遍历给定的区间,对于当前考虑的数\(x\),先判断num[x]上的记录,如果是素数则加入prime数组中。然后在把这个数分别乘以prime数组上的素数,将这些积也标记为合数,如果碰到x%prime[j]==0的情况,则跳出循环,继续考虑\(x+1\)
这样做可以保证筛每个数都能做到不重不漏,而此算法有别于普通线性筛的关键在于x%prime[j]==0这条语句。
现在大概阐释下算法的正确性。首先,正确性有赖于 算数基本定理 ,关于此定理的具体内容在此不再赘述。此处引用网上的一个证明。

对于一个数\(c=ab\)(\(b\)\(c\)的最小质因数),当通过该算法的循环循环至\(cb\)时,易得此时\(c \text{ mod } b=0\),如果此时继续循环至\(b\)后面的一个素数\(d\),则有:\(cd=abd=ad \times b\),因为\(d>b\),所以\(a d>c\)。当循环从\(c\)继续查找到\(ad\)时我们发现当\(ad\)再次与素数\(b\)相乘时,就又对\(cd\)进行了一次操作,出现了冗余,所以在if(n%prime[j]==0)成立时要将该层循环跳出。

核心代码如下:

for(int i=2;i<=n;++i)
{
    if(!num[i]) prime[++cnt]=i;
    for(int j=1;j<=cnt && i*prime[j]<=n;++j)
    {
        num[i*prime[j]]=1;
        if(i%prime[j]==0) break;
    }
}

转载于:https://www.cnblogs.com/wzzyr24/p/11433259.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值