欧拉线性筛。
对于它的复杂度的计算大概思考了很久。
procedure build_prime; var i,j:longint; begin fillchar(vis,sizeof(vis),true); prime[0]:=0; for i:=2 to maxn do begin if vis[i] then begin inc(prime[0]); prime[prime[0]]:=i; end; for j:=1 to prime[0] do begin if i*prime[j]>maxn then break; vis[i*prime[j]]:=false; if i mod prime[j]=0 then break; end; end; end;
if i mod prime[j]=0 then break;
首先这句话的正确性显然,一旦i mod prime[j]=0,i与后面一些素数的乘积都可以用prime[j]乘上一个合数来得到。
同是也就保证了每个合数都是被它最小的质因子筛掉。
证明:
假设当前prime[j]不是最小质因子,最小的质因子为p
因为p|prime[j]*i ,p不整除prime[j],∴p|i
而p<prime[j],在之前p出现的时候i即被break掉
所以这种情况不存在。
所以每个合数都是被它最小的质因子筛掉。
也就是对于每一个合数,vis的赋值只做一次,而观察下面的循环次数也就是vis做的次数
所以时间复杂度为O(n).
至于POJ1595,不过是一道初一的时候就做过的水题...
问我为什么会要在标题上写...当然是为了好看啦...>_<