歐拉篩模板
#define N 1000
bool check[N];//數組表示第i個數是否爲素數,是爲true,不是爲false;
int prime[N];//數組存放素數序列,從0開始都是素數(遞增序列)
int min_prime[N];//數組存放每個數的最小素因數
int Prime(int n){//返回n中素數的個數
memset(check,true,sizeof(check));//初始化,所有都爲true,篩過後標記爲false
int sum=0,i,j;//sum爲素數序列中素數的個數。
for(i=2;i<=n;i++){
if(check[i])//當i爲素數時
prime[sum++]=i;//將i存放到素數序列中
for(j=0;j<sum&&i*prime[j]<=n;j++){
check[i*prime[j]]=false;//把所有素數的i倍全部標記爲false
min_prime[i*prime[j]]=prime[j];//存放最小素因數
if(i%prime[j]==0) //當i是prime[j]的倍數時,跳出循環
break;
}
}
return sum;
}
歐拉篩與普通篩法不一樣的是所有合數都被其最小素因子篩去且僅篩一次。
關鍵代碼就是
if(i%prime[j]==0) //當i是prime[j]的倍數時,跳出循環
break;
如果不跳出循環,那麼下一步就是將 check[i * prime[j+1]] 變成 false,但是,如果 i 爲 prime[j] 的倍數,即 i = k * prime[j].
那麼,i * prime[j+1]=k * prime[j] * prime[j+1] = ( k * prime[j+1] ) * prime[j] = k' * prime[j]。當外層循環 i 增長到 k' 時,會將 k' * prime[j] 篩去(因爲 prime[j]< prime[j+1])。