线性筛法

来源:互联网 发布:软件可靠性英文 编辑:程序博客网 时间:2024/05/24 01:19

当求质数时,我们用普通筛法,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
原创粉丝点击