【模板】线性筛素数
如题,给定一个范围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<iostream>
#include<algorithm>
#include <cstring>
#include<vector>
#include<math.h>
using namespace std;
int su[10000010];//素数表,默认为0,值为0代表是素数,值为1代表不是素数
bool out[10000010];//判断素数,默认为false 如果值为true,代表这个数不是质数
void aishai(int mm) { //埃式筛法 用时: 3761ms / 内存: 41580KB 一个测试点999ms
su[0] = su[1] = 1;
for (int i = 2; i <= sqrt(mm); i++) {
if (su[i])continue;
for (int j = i << 1; j <= mm; j += i)
su[j] = 1;
}
}
void olshai(int mm) //欧拉筛法 用时: 1654ms / 内存: 18052KB
{
vector<int>cun; //储存素数
out[0]=out[1] = 1; //0和1不是质数 没有,错一个测试点
for (int i = 2; i <= mm; i++)
{
if (!out[i])cun.push_back(i); //没被筛过,肯定是素数
int len = cun.size();
for (int j = 0; j < len&&i*cun[j] <= mm; j++) { //<=mm 没有等于的话,错两个测试点
out[i*cun[j]] = true; //素数的倍数肯定不是素数
if (i%cun[j] == 0)break; //主要优化点,如果i是素数的倍数的话,就结束
}
}
return;
}
bool issu(int a) { //最快判断素数 用时: 842ms / 内存: 780KB
if (a == 0 || a == 1)return 0;
if (a == 2 || a == 3)return 1;
if (a % 6 != 1 && a % 6 != 5) return 0;
int qa = sqrt(a);
for (int i = 5; i <= qa; i++)
if (a%i == 0 || a % (i + 1) == 0)return 0;
return 1;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
int n, m,t;
cin >> n>>m;
//aishai(n);
for (int i = 0; i < m; i++) {
cin >> t;
if (!issu(t))
cout << "No\n";
else
cout << "Yes\n";
}
return 0;
}