這裏介紹兩種篩法
一般篩法(埃拉託斯特尼篩法):
基本思想:素數的倍數一定不是素數
實現方法:用一個長度爲N+1的數組保存信息(0表示素數,1表示非素數),先假設所有的數都是素數(初始化爲0),從第一個素數2開始,把2的倍數都標記爲非素數(置爲1),一直到大於N;然後進行下一趟,找到2後面的下一個素數3,進行同樣的處理,直到最後,數組中依然爲0的數即爲素數。
下面我們來介紹一波真正的線性篩(歐拉篩法):
我們發現在上面的篩法中有的數字是多個素數的倍數,也就是說它可能會被重複計算多次,比如說6同時是2與3的倍數,它在計算時就被訪問了兩次,這樣會導致效率低下,所以在下面的算法中我們考慮如何優化這種情況。
模版題
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,g;
int prime[10000001];
bool flag[10000001]={1,1};
int read();
int main()
{
freopen("P3383.in","r",stdin);
freopen("P3383.out","w",stdout);
cin>>n>>m;
for(int i=2;i<=n;i++)
{
if(!flag[i]) prime[++g]=i;
for(int j=1;j<=g && prime[j]*i<=n;j++)
{
flag[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
for(int i=1;i<=m;i++)
{
int num; num=read();
if(flag[num]==1) printf("No\n");
else printf("Yes\n");
}
return 0;
}
int read()
{
int x=0,f=1; char c=getchar();
while(c<'0' || c>'9') {if(c=='-') f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*=f;
}