【模板】线性筛素数

流过昼夜 提交于 2020-04-04 06:15:04

【模板】线性筛素数

如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)

输入输出格式

输入格式:

第一行包含两个正整数N、M,分别表示查询的范围和查询的个数。

接下来M行每行包含一个不小于1且不大于N的整数,即询问该数是否为质数。

输出格式:

输出包含M行,每行为Yes或No,即依次为每一个询问的结果。

输入输出样例

输入样例#1: 
100 5
2
3
4
91
97
输出样例#1: 
Yes
Yes
No
No
Yes

说明

时空限制: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 个质数.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!