我们先来看欧拉筛法
•为什么叫欧拉筛呢?这可能是跟欧拉有关
•但是为什么叫线性筛呢?因为它的复杂度是线性的,也就是O(n),我们直接来看代码
#include<cstdio> #include<iostream> #include<cstdlib> #include<iomanip> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<time.h> using namespace std; int tot,n,b[9999999],pri[9999999];//b[i]存的是i是否为质数,0为质数,1为合数;pri[i]存的是第i个质数 inline void shai() {
//b[1]=1; for(int i=2;i<=n;i++)//从2到n,因为1不是质数可以跳过,当然有的时候可能会用到b[1],这个时候需要赋特值如上 { if(!b[i])pri[++tot]=i; for(int j=1;j<=tot&&i*pri[j]<=n;++j) { b[i*pri[j]]=1; if(i%pri[j]==0)break;//如果i%pri[j]==0,就说明是i的倍数的数一定是某质数的倍数,这个时候就可以把它去掉从而节省时间 } } } int main() { cin>>n; shai(); for(int i=1;i<=tot;i++) { cout<<pri[i]<<endl;//这里是输出n以内的质数,如果想判断一个数是否为质数可以看b[i] } }
下面来看模板题
题目描述
如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)
输入输出格式
输入格式:
第一行包含两个正整数N、M,分别表示查询的范围和查询的个数。
接下来M行每行包含一个不小于1且不大于N的整数,即询问该数是否为质数。
输出格式:
输出包含M行,每行为Yes或No,即依次为每一个询问的结果。
输入输出样例
说明
时空限制:500ms 128M
数据规模:
对于30%的数据:N<=10000,M<=10000
对于100%的数据:N<=10000000,M<=100000
样例说明:
N=100,说明接下来的询问数均不大于100且不小于1。
所以2、3、97为质数,4、91非质数。
故依次输出Yes、Yes、No、No、Yes。
程序如下:
#include<cstdio> #include<iostream> #include<cstdlib> #include<iomanip> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<time.h> using namespace std; int tot,n,m,b[9999999],pri[9999999],a[9999999]; inline void shai() { for(int i=2;i<=n;i++) { if(!b[i])pri[++tot]=i; for(int j=1;j<=tot&&i*pri[j]<=n;++j) { b[i*pri[j]]=1; if(i%pri[j]==0)break; } } } int main() { cin>>n>>m; shai(); for(int i=1;i<=m;i++) { cin>>a[i];//当然这里不用数组也可以 } for(int i=1;i<=m;i++) { if(a[i]==1) { cout<<"No"<<endl; } else { if(b[a[i]]==0) cout<<"Yes"<<endl; else cout<<"No"<<endl; }//这里就是判断素数用b[i]的值,和上边的欧拉筛法模板是一样的 } return 0; }