埃拉托斯特尼筛法:
#include<cstdio>
#include<iostream>
using namespace std;
bool notprime[10000005];
void checkprime(int n)
{
for(int i=2;i<=n;i++){//注意线性筛法做完以后1是没有被标记的...
if(notprime[i])continue;//如果已经被标记为合数,那就滚蛋
for(int j=i;j<=n/i;j++)//注意这里一定要小心j*i可能爆int的事实,写成
//j=i*i的时候也是一样要小心!!!最好用long long
notprime[j*i]=true;//标记合数
}
}
int main()
{
int n,m,i;
cin>>n>>m;
checkprime(n);notprime[1]=true;//特别注意要标记1
for(i=1;i<=m;i++){
int t;
scanf("%d",&t);
if(notprime[t])cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
return 0;
}
线性筛法:
#include<cstdio>
#include<iostream>
using namespace std;
int v[10000005],prime[10000000],cnt=0;//v记录每个数的最小质因数,prime记录素数
void checkprime(int n)
{
for(int i=2;i<=n;i++){
if(v[i]==0){//如果i是素数
v[i]=i;
prime[++cnt]=i;
}
for(int j=1;j<=cnt;j++){
if(prime[j]>v[i]||prime[j]>n/i)//如果当前的质数已经比I的最小质因数大了,那么就没有必要再继续下去了,因为后面的i*prime[j]
break;//肯定已经被v[i]或者其他更小的质数标记过了;同时,超过n自然也是不用管了
v[i*prime[j]]=prime[j];//标记最小质因数
}
}
}
int main()
{
int n,m;
cin>>n>>m;
checkprime(n);
for(int i=1;i<=m;i++){
int t;scanf("%d",&t);
if(v[t]==t)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}