一般筛,每个数被筛次数会出现>1,复杂度近似于O(NloglogN):
//一般筛
var vis:array[0..1000005]of boolean;
i,j,n:longint;
begin
assign(input,'xxs.in');reset(input);
assign(output,'xxs.out');rewrite(output);
fillchar(vis,sizeof(vis),1);
readln(n);
for i:=2 to trunc(sqrt(n)) do
if vis[i] then
for j:=2 to n div i do vis[i*j]:=false;
for i:=2 to n do
if vis[i] then writeln(i);
close(input);close(output);
end.
线性筛,关键在于if (i%prime[j]==0) break,就避免了一个数被重复筛,复杂度O(N):
//线性筛
#include<cstdio>
#include<cstring>
int prime[1000005];
int n,cnt;
bool vis[1000005];
using namespace std;
int main(){
freopen("xxs.in","r",stdin);
freopen("xxs1.out","w",stdout);
int n,cnt;
scanf("%d",&n);
cnt=0;
memset(vis,0,sizeof(vis));
for (int i=2;i<=n;i++){
if (!vis[i])prime[++cnt]=i;
for (int j=1;j<=cnt&&prime[j]*i<=n;j++){
vis[prime[j]*i]=1;
if (i%prime[j]==0) break;
}
}
for (int i=1;i<=cnt;i++) printf("%d\n",prime[i]);
return 0;
}
【写的有漏洞的,欢迎路过大神吐槽】
2016/12/22 17:40:40
Ending.