线性筛法

当求质数时,我们用普通筛法,O(n log n)解决,但n很大时,就会爆掉,这时就需要这一种很强大的筛法——线性筛法来解决,所谓线性,就是O(n)咯。

当我们用普通筛法时,要筛掉一个数n,可能会被筛很多次,这就造成了累赘,比如36:
3 * 12时被筛掉一次,18 * 2时被筛掉一次,这样就会有累赘,那么我们想想:我们在枚举j去筛掉i*j ,如果j|i,(显然j是一个质数)的话,就break掉,就可以变成O(n)了,这样显然是可行的:当筛12 * 2后,2|12,break掉,那这样就不会筛12 * 3,当筛18 * 2的时候,才会真正筛掉36,然后break掉。那么我们就得出了线性筛法的框架:

  1. 假如i没被筛,加入质数表
  2. 不管i有没有被筛,从小到大枚举质数j,筛掉i*j,然后如果j|i,break。

Codes:

procedure GetPrimes;
    var i,j:longint;
begin
    for i:=2 to top do //要求2~top的质数
    begin
        if not bz[i] then  //加入质数表
        begin
            inc(top);
            pr[top]:=i;
        end;
        for j:=1 to top do  //筛掉后面的
        begin
            if pr[j]*i>top then break;
            bz[pr[j]*i]:=true;
            if i mod pr[j]=0 then break;  //剪掉不必要的
        end;
    end;
end;

注:x|y表示y mod x=0。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值