1. 程式人生 > >[模板]線性篩素數(尤拉篩法)

[模板]線性篩素數(尤拉篩法)

用途

$O(n)$處理出n以內所有素數

原理

使用 合數=最大因數(除1和本身外)*最小質因數 的原理來篩,每個數只會被篩一次

對於每個數i,令它是某數的最大因數,然後從小到大地找<=i的素數j,則i*j是合數

直到找到某個j使得$i\%j==0$,因為再往後的話,j'> i的某個因子,我們能交換j'和i的這個因子,所以i不是i*j'的最大因數(或者說i*j'的最小質因數是剛才的那個j),再往後做沒有意義

例題

luogu3383

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4
#include<queue> 5 using namespace std; 6 const int maxn=10000010; 7 8 int rd(){ 9 int x=0;char c=getchar();int neg=1; 10 while(c<'0'||c>'9'){ 11 if(c=='-') neg=-1;c=getchar(); 12 } 13 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 14 return
x*neg; 15 } 16 17 int N,M; 18 int pri[maxn],cnt; 19 bool isp[maxn]; 20 21 int main(){ 22 int i,j,k; 23 N=rd();M=rd(); 24 memset(isp,1,sizeof(isp));isp[0]=isp[1]=0; 25 for(i=2;i<=N;i++){ 26 if(isp[i]) pri[++cnt]=i; 27 for(j=1;j<=cnt&&i*pri[j]<=N;j++){
28 isp[i*pri[j]]=0; 29 if(i%pri[j]==0) break; 30 } 31 } 32 33 for(i=1;i<=M;i++){ 34 if(isp[rd()]) printf("Yes\n"); 35 else printf("No\n"); 36 } 37 }