最一般的素數篩思想很簡單,對於不超過maxx的每個非負整數p,刪除2p,3p,4p,……,然後剩下的就是素數,複雜度O(nlogn),因爲對內層循環n/2+n/3+......+n/n 小於 1+1/2+1/3+...+1/n=ln(n+1)+γ,其中γ爲歐拉常數≈0.577218
應當注意,1不是素數哦~
這樣已經不慢,但由於所有非素數都能由素數與素數的乘積表示,又可以優化如下
int maxx=1000000;
long long prime[maxx];
bool isPrime[maxx];
void Eratosthenes()
{
memset(isPrime,1,sizeof(isPrime));
isPrime[1]=0;
for(int i=2;i<=maxx;++i)
{
if(isPrime[i])
{
for(int j=2*i;j<=maxx;j+=i)
isPrime[j]=0;
}
}
}
時間複雜度是O(nloglogn)
但是還能再優化,內層循環不必從i*2開始,它已經在i=2時候就被篩掉了。優化如下:
int maxx=1000000;
long long prime[maxx];
bool isPrime[maxx];
void Eratosthenes()
{
memset(isPrime,1,sizeof(isPrime));
isPrime[1]=0;
int m=sqrt(maxx+0.5)
for(int i=2;i<=m;++i)
{
if(isPrime[i])
{
for(int j=i*i;j<=maxx;j+=i)
isPrime[j]=0;
}
}
}