【模板】线性筛素数
如题,给定一个范围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; }
10 以内共 4 个质数.
100 以内共 25 个质数.
1000 以内共 168 个质数.
1*10^4 以内共 1229 个质数.
1*10^5 以内共 9592 个质数.
1*10^6 以内共 78498 个质数.
1*10^7 以内共 664579 个质数.
1*10^8 以内共 5761455 个质数.
来源:https://www.cnblogs.com/52dxer/p/10421968.html