【模板】线性筛素数

zzx:做一下【模板】欧拉定理吧

yxy:啥玩意啊OAO

zzx:噢对了,你会不会算Phi

yxy:那是啥啊qwq

zzx:……你会不会写欧筛

yxy:不会!(逃)

zzx:qwq你先去做一下埃筛模板吧


给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)
1.暴力无脑筛素数qwq

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define MAXN 10000005
#define MAXM
#define scanf(a) scanf("%d",&a)
#define print(a) printf("%d",&a)
#define printn(a) printf("%d
",a)
using namespace std;
int n,m,ans;
bool prime[MAXN]; 



void init()
{
	scanf(n); scanf(m);
	memset(prime,true,n+1);
	prime[0]=false; prime[1]=false;
}
void f_prime()
{
	for (int i=3;i<=n;i++)
	{
		for (int j=2;j<=sqrt(i);j++)
		{
			if (!(i%j))
			{
				prime[i]=false;
				break;
			}
		}
	}
}
void start()
{
	f_prime();
	for (int i=1,a;i<=m;i++)
	{
		scanf(a);
		if (prime[a])
		{
			printf("Yes
");
			continue;
		}
		printf("No
");
	}
}
int main()
{
	init();
	start();
	return 0; 
}

保你T飞www

2.埃拉托斯特尼筛法(其实这才叫(普通筛法))

主要思想-->素数的倍数一定不是一个素数

初始化,将每个数都标记为是素数

然后找到一个当前被标记为素数的(i)的就将(i)的倍数都标记为非素数。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define MAXN 10000005
#define MAXM
#define scanf(a) scanf("%d",&a)
#define print(a) printf("%d",a)
#define printn(a) printf("%d
",a)
using namespace std;
int n,m;
bool prime[MAXN];



void init()
{
	scanf(n); scanf(m);
	memset(prime,true,n+1); 
	prime[0]=false; prime[1]=false;
}
void f_prime()
{
	for (int i=2;i<=n;i++)
	{
		for (int j=i+i;j<=n;j+=i)
		{
			prime[j]=false;
		}
	}
}
void start()
{
	f_prime();
	for (int i=1,a;i<=m;i++)
	{
		scanf(a);
		if (prime[a])
		{
			printf("Yes
");
			continue;
		}
		printf("No
");
	}
}
int main()
{
	init();
	start();
	return 0;
}

3.欧拉筛法

算是个埃筛的优化……但是常数比较大

我们发现此方法还可以继续优化,因为上述的方法中,每一个有多组因数可能会被筛多次

即一个合数(x)与一个质数(y)的乘积可以表示成一个更大的合数(Z)与一个更小的质数(a)的乘积

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define MAXN 10000005
#define MAXM
#define scanf(a) scanf("%d",&a)
#define print(a) printf("%d",a)
#define printn(a) printf("%d
",a)
using namespace std;
int n,m,tot=0;
bool prime[MAXN];
int P[MAXN];


void init()
{
	scanf(n); scanf(m);
	memset(prime,true,sizeof(prime));
	prime[0]=false; prime[1]=false;
}
void f_prime()
{
	for (int i=2;i<=n;i++)
	{
		if (prime[i])
		{
			P[++tot]=i;
		}
		for (int j=1;j<=tot&&i*P[j]<=n;j++)
		{
			prime[i*P[j]]=false;
			if (!(i%P[j]))
			{
				break;
			}
		}
	}
}
void start()
{
	f_prime();
	for (int i=1,a;i<=m;i++)
	{
		scanf(a);
		if (prime[a])
		{
			printf("Yes
");
			continue;
		}
		printf("No
");
	}
}
int main()
{
	init();
	start();
	return 0;
}

(yxy的黑历史:在jzwc的摸底比赛中 可以暴力过的判断素数 我打了个超大的表(((()

(谨以此时刻提醒自己。。。自己太菜了所以要更努力)

原文地址:https://www.cnblogs.com/Kan-kiz/p/10636027.html