素数筛的用处还是蛮多的,有很多和素数有关的题都要用到素数筛,所以有一个高效的筛法自然是非常好的吖,普通筛法(暴力筛法)就不说了,因为有了高效的也没人在会用普通筛法了吧。
线性素数筛是用每一个合数的最小的质因数筛掉它,这个体现在代码里的 if(i%prime[j]==0)break; 这句话里,因为如果这里不跳出的话,j会继续向上枚举,这时i*peime[j]的最小的质因数是之前的那个prime[j]而不是现在的prime[j],而一旦出现这样的情况,就不能保证每个数都被自己最小的质因数筛掉。而加上了那句话之后,时间复杂度保证就是线性的。
模板:https://www.luogu.org/problemnew/show/P3383
代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,m; 5 bool vis[10000003]; 6 int prime[1000003]; 7 int cnt; 8 int main() 9 { 10 scanf("%d%d",&n,&m); 11 vis[0]=vis[1]=1; 12 for(int i=2;i<=n;++i) 13 { 14 if(!vis[i])prime[++cnt]=i; 15 for(int j=1;j<=cnt&&i*prime[j]<=n;++j) 16 { 17 vis[i*prime[j]]=1; 18 if(i%prime[j]==0)break; 19 } 20 } 21 while(m--) 22 { 23 int x; 24 scanf("%d",&x); 25 if(!vis[x])printf("Yes\n"); 26 else printf("No\n"); 27 } 28 return 0; 29 }