![[POJ1595]欧拉线性筛(虽然这道题不需要...) [POJ1595]欧拉线性筛(虽然这道题不需要...)](https://image.shishitao.com:8440/aHR0cHM6Ly9ia3FzaW1nLmlrYWZhbi5jb20vdXBsb2FkL2NoYXRncHQtcy5wbmc%2FIQ%3D%3D.png?!?w=700)
欧拉线性筛。
对于它的复杂度的计算大概思考了很久。
procedure build_prime;
var i,j:longint;
begin
fillchar(vis,sizeof(vis),true);
prime[]:=;
for i:= to maxn do
begin
if vis[i] then
begin
inc(prime[]);
prime[prime[]]:=i;
end;
for j:= to prime[] do
begin
if i*prime[j]>maxn then break;
vis[i*prime[j]]:=false;
if i mod prime[j]= 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,不过是一道初一的时候就做过的水题...
问我为什么会要在标题上写...当然是为了好看啦...>_<