【模板】线性筛质数

本文介绍了一种高效的线性筛素数算法,通过确保每个合数仅由其最小质因数筛除,实现O(n)的时间复杂度。文章详细解释了算法的核心思想,并通过代码示例展示了如何在实践中应用该算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

核心思想:

保证每个合数只会被它的最小质因数筛去,因此每个数只会被标记一次,所以时间复杂度是O(n)

此过程中保证了两点

  1. 合数一定被干掉了...
  2. 每个数都没有被重复地删掉

 

代码

 

#include<iostream>
#include<cstdio>
#include<cstring>
#define f(i,a,b)    for(register int i=a;i<=b;++i)
#define fd(i,a,b)    for(register int i=a;i>=b;--i)
using namespace std;
const int N=10000000+7;
int n,m,f[N],tot;
bool visit[N];
//visit[i]如果被标记了 那么就不是素数
inline int read() {
	int data=0,w=1;
	char ch=0;
	while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
	if(ch=='-') w=-1,ch=getchar();
	while(ch>='0' && ch<='9') data=data*10+ch-'0',ch=getchar();
	return data*w;
}

inline void write(int x) {
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}

inline void pd(int Max) {
	visit[1]=1;
	f(i,2,Max) { //枚举每一个数 顺便枚举倍数
		if(!visit[i])//要是没标记到那么就是素数
			f[++tot]=i;
		for(int j=1; j<=tot && i*f[j]<=Max; j++)
			//这里是枚举前面的每一个素数
		{
			visit[i*f[j]]=1;//把前面的素数倍数都标记上
			if(i % f[j]==0)    break;//如果不是最小质因子就退出
			/****************************
			    为什么这句话可以忽略掉不是最小质因子 而保证时间复杂度呢
			    首先 visit[]里面的素数都是严格递增的
			    如果当前的i含有visit[j] 不妨设 i=visit[j]*k
			    下一个数 P=i*visit[j+1]肯定可以写成 P=visit[j]*k*visit[j+1]
			    所以P肯定会在 i=k*visit[j+1] 的时候筛掉
			    所以这句话可以使得是最小质因子就退出
			*****************************/
		}
	}
}

int main() {
//    ios::sync_with_stdio(false);
	n=read();
	m=read();
	pd(n);
	f(i,1,m) {
		int a=read();
		if(visit[a])    puts("No");
		else puts("Yes");
	}
	return 0;
}

 

 

 

代码引自luogu

转载于:https://www.cnblogs.com/bbqub/p/7668622.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值