首页 > 编程语言 >【算法专题】筛质数

【算法专题】筛质数

时间:2024-02-05 18:23:27浏览次数:24  
标签:专题 int 质数 算法 那么 倍数 primes 复杂度

筛质数的三种方法

什么是质数?
只能够被 1 和它本身整除的数叫做质数

1、朴素筛法

那么我们从定义出发,假设我们要判断 \(n\) 是否是质数,我们从 \(1\) 开始枚举每一个数,一直到 \(n\) 看看有没有其他的数能够被 \(n\) 整除,如果没有,那么 \(n\) 就是质数。

假设我们要筛出从 \(1\) ~ \(n\) 之间的质数,那么时间复杂度为 \(O(n\sqrt n)\)。

int primes[N], cnt;

bool is_primes(int x)
{
	for (int i = 2; i <= sqrt(x); i++) // 小优化,可以枚举到 根号n
		if (x % i == 0)
			return false;
	return true;
}

void init(int n) // 筛质数
{
	for (int i = 2; i <= n; i++)
		if (is_primes(i))
			primes[cnt++] = i;
}

那么我们可不可以想到,质数的倍数是不是一定不是质数了,那么我们可以进行一次优化。

int primes[N], cnt;
bool st[N]; // 标记是否是被筛过了

void init(int n)
{
	for (int i = 2; i <= n; i++)
	{
		if (!st[i]) primes[cnt++] = i; // 把质数存起来
		for (int j = i + i; j <= n; j += i) // 不管i是不是质数,枚举i的倍数,筛掉
			st[j] = true;
	}
}

这样时间复杂度就变成了 \(O(n\log n)\)

2、埃氏筛(埃拉托斯特尼筛法)

我们知道,朴素筛法就是一直枚举,把它枚举到的所有的数的倍数都筛掉,那么我们想想可不可能合数不用枚举它的倍数呢,因为质数的倍数一定可以表示成某个合数,所以我们可以只把质数的倍数给筛掉。

埃氏筛就是从另一个角度来看,把所有质数的倍数给筛掉。

这样时间复杂度就变成了 \(O(n \log \log n)\)

int primes[N], cnt;
bool st[N]; // 标记是否是被筛过了,没被筛过肯定是质数

void init(int n)
{
	for (int i = 2; i <= n; i++)
	{
		if (!st[i])
		{
			primes[cnt++] = i; // 把质数存起来
			for (int j = i + i; j <= n; j += i) // 枚举i的倍数,筛掉
				st[j] = true;
		}
	}
}

3、欧拉筛(线性筛)

我们使用埃氏筛后,时间复杂度变得很低了,但是依然不是线性的,说明还是可以有优化的空间,那么大家想一想埃氏筛的过程,我们是不是有重复的筛数的情况呀。

比如说遍历到 \(3\) ,那么是不是 \(15\) 是 \(3\) 的倍数,被筛掉一次,遍历到 \(5\) 的时候,\(15\) 也是 \(3\) 的倍数,是不是又要筛一次呀,所以我们进行了很多重复的操作。

那么欧拉筛就解决了这个问题,它加了一个优化,它也是筛质数的倍数,但是它加了一个判断条件,假如要筛的数是之前存下来的质数的倍数,那么我们就直接break,开始进行筛下一个数。

int primes[N], cnt;
bool st[N];

void init(int n)
{
	for (int i = 2; i <= n; i++)
	{
		if (!st[i]) primes[cnt++] = i;
		for (int j = 0; primes[j] <= n / i; j++)
		{
			st[i * primes[j]] = true; // 用质因子筛
			if (i % primes[j] == 0) break;
			// 当走到这里时,这个质因子是i能整除的最小的了,我们不用判断后面的质因子了
			// 如果不加优化,那么这个数就会被重复筛,我们举的例子。
		}
	}
}

那么我们可以清楚的看到,每个数都被筛了,并且只筛了一次,所以时间复杂度为 \(O(n)\)

标签:专题,int,质数,算法,那么,倍数,primes,复杂度
From: https://www.cnblogs.com/yhgm/p/18008611

相关文章

  • 2024牛客寒假算法基础集训营2
    题目链接A.模拟#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;voidsolve(){intn;cin>>n;while(n--){inta,b,c;cin>>a>>b>>c;intans=0;if(a==150)ans+=1......
  • 【教3妹学编程-算法题】1696. 跳跃游戏 VI
    3妹:好冷啊,冻得瑟瑟发抖啦2哥 :没想到都立春了还这么冷啊~3妹:暴雪、冻雨、大雨,这天气还让不让人活啦!!!2哥 :哎,好多人都滞留的高铁站了,没法回家了3妹:我还不知道今天怎么回家呢,惨。2哥:3妹,要不别回去了吧,我们就地过年3妹:切,这里更冷,每天抖啊抖,跳啊跳才能缓解寒冷,我们家那儿可是有暖气......
  • 文心一言 VS 讯飞星火 VS chatgpt (194)-- 算法导论14.3 2题
    二、用go语言,改写INTERVAL-SEARCH的代码,使得当所有区间都是开区间时,它也能正确地工作。文心一言,代码正常运行:在Go语言中,处理开区间(openintervals)时,我们需要特别注意区间的边界条件。开区间不包括其端点,因此在比较时不能使用等于(==)操作符。以下是一个使用Go语言实现的INTERVAL......
  • 【算法】LCT
    参考资料OI-Wiki:LCTFlashHu:LCT总结——概念篇前言第一次学,感觉这玩意挺抽象……只能写下博客巩固一下印象。概念前置知识:树链剖分,Splay给定一棵树,没有任何的更改操作,询问一些有关树上路径问题(如两点之间的权值和),就可以用树上倍增。而如果在此基础上增添了更改某个点......
  • 可控概率抽奖算法
    说明本文PHP语言去实现,只实现核心可控概率引擎,库存判断等其它业务需要其它代码配合实现。代码/***@function封装可控概率的抽奖功能*@param$arrarray数据集合*@param$weight_keystring权重字段*@returnarray被选中的元素*/funct......
  • 【专题】2023年碳市场、净零碳、双碳行业报告汇总PDF合集分享(附原数据表)
    原文链接: https://tecdat.cn/?p=35142原文出处:拓端数据部落公众号中国碳金融创新发展是一个备受关注的话题。本白皮书报告合集综合了中国特色与国际经验、理论研究与前沿实践、监管导向与市场声音,全面探讨了金融力量在中国碳市场发展中的角色与作用。阅读原文,获取专题报告合集......
  • R语言LASSO特征选择、决策树CART算法和CHAID算法电商网站购物行为预测分析
    全文链接:http://tecdat.cn/?p=32275原文出处:拓端数据部落公众号本文通过分析电子商务平台的用户购物行为,帮助客户构建了一个基于决策树模型的用户购物行为预测分析模型。该模型可以帮助企业预测用户的购物意愿、购物频率及购买金额等重要指标,为企业制定更有针对性的营销策略提供......
  • r语言有限正态混合模型EM算法的分层聚类、分类和密度估计及可视化|附代码数据
    原文链接:http://tecdat.cn/?p=23825最近我们被客户要求撰写关于有限正态混合模型EM算法的研究报告,包括一些图形和统计输出。简介本文介绍了基于有限正态混合模型在r软件中的实现,用于基于模型的聚类、分类和密度估计。提供了通过EM算法对具有各种协方差结构的正态混合模型进行参......
  • 2024牛客寒假算法基础集训营1 J 又鸟之亦心 题解
    Question2024牛客寒假算法基础集训营1J又鸟之亦心Solution挺好的一个题,给了我很多启发显然,先二分最大值\(D\),关键在于\(check\)怎么写考虑到两个人是相对的,第\(i\)次之后肯定有一个人在\(a_i\),具体是谁不重要,也不需要关注是怎么走过来的,我们需要去维护另外一个人可......
  • 竞赛图专题突破
    目录定义性质一、兰道定理(竞赛图的判定)比分序列:将每个点的出度从小到大排序的序列。定理内容:定理证明拓展二、竞赛图缩点后拓扑序成链状,拓扑序小的点向所有拓扑序比它大的点连边。(1)与SCC,拓扑序相关推论:1.根据成链状容易发现当不存在位置i满足以下条件,图为强连通图。2.在同一个SCC......