关闭

线性筛法

标签: 数学
154人阅读 评论(0) 收藏 举报

当求质数时,我们用普通筛法,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。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:21449次
    • 积分:1111
    • 等级:
    • 排名:千里之外
    • 原创:91篇
    • 转载:5篇
    • 译文:1篇
    • 评论:4条
    最新评论