【欧拉筛法】洛谷 P3383 线性筛素数

news2024/9/20 18:42:20

3383. 线性筛素数

文章目录

  • 题目描述
    • 输入格式:
    • 输出格式:
    • 数据范围
    • 输入样例
    • 输出样例
  • 方法一:埃氏筛法
    • 解题思路
    • 代码
    • 复杂度分析:
  • 方法二:欧拉筛法
    • 解题思路
    • 代码
    • 复杂度分析:
  • 两种方法对比
    • 埃氏筛法
    • 欧拉筛法

题目描述

给定一个范围 n,有 q 个询问,每次输出第 k 小的素数。

输入格式:

第一行包含两个正整数 n、q,分别表示查询的范围和查询的个数。
接下来 q 行每行一个正整数 k,表示查询第 k 小的素数。

输出格式:

输出 q 行,每行一个正整数表示答案。

数据范围

  • 对于 100 % 的数据, n = 1 0 8 , 1 ≤ q ≤ 1 0 6 ,保证查询的素数不大于 n 对于100\%的数据,n = 10^8,1\leq q\leq10^6,保证查询的素数不大于 n 对于100%的数据,n=1081q106,保证查询的素数不大于n

输入样例

100 5
1
2
3
4
5

输出样例

2
3
5
7
11

方法一:埃氏筛法

解题思路

假设要求 0 - 20 之间的素数。
从 2 开始遍历每个数,因为 0 和 1 都不是素数。2 是最小的素数。
isPrime 布尔数组标记当前下标是否为素数,true 是素数,false 不是素数。
prime 数组用于存放素数。
方法:
如果 isPrime[i] 为 true,说明 i 为素数,因为它不能被更小的数整除(除了 1),然后把 i 的所有倍数都给划去;
为什么 j = i 呢,而不是等于 2 呢?
因为 i * 2 到 i * (i - 1) 在之前已经被划去,为了避免重复操作,所以 j 从 i 开始。
如果 isPrime[i] 为 false,说明 i 不是素数,它已经被划去了。
在这里插入图片描述
刷题平台的时间限制一般为 1s 或 2s,这就要求操作次数控制在 1 0 7 10^7 107 以内。
因为埃氏筛法的时间复杂度为 O ( n × l o g ( l o g   n ) ) O(n \times log(log\ n)) O(n×log(log n)),本题 n = 1 0 8 n = 10^8 n=108,所需操作的次数会远远大于 1 0 7 10^7 107,从而导致超时,故只好用欧拉筛法。

代码

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int N = 1e8 + 10;

bool isPrime[N];
int n, q;
int prime[N];
int cnt = 0;

void GetPrime() {
	// 将布尔数组初始化,全部置为 true,1 即为 true
    memset(isPrime, 1, sizeof(isPrime));
    isPrime[0] = false, isPrime[1] = false;
	for(int i = 2; i <= n; i++) {
		// 没有被划去过,说明 i 为素数
		if(isPrime[i]) {
			// 如果 i 是素数,将 i 的倍数都给划去
			for(int j = i; i * j <= n; j++) 
				isPrime[i * j] = false;
			// 把素数保存起来 
			prime[++cnt] = i;	
		}
	}
}

int main() {
	scanf("%d%d", &n, &q);
	GetPrime();
	while(q--) {
		int k;
		scanf("%d", &k);
		printf("%d\n", prime[k]);
	}
	return 0;
}

复杂度分析:

  • 时间复杂度: O ( n × l o g ( l o g   n ) ) O(n\times log(log \ n)) O(n×log(log n))
  • 空间复杂度: O ( n ) O(n) O(n)

方法二:欧拉筛法

解题思路

因为埃氏筛法在把合数筛掉的过程中,会把一个合数重复筛掉多次,会浪费时间。
而欧拉筛法只会将一个合数筛掉一次,具有线性的时间复杂度,故而又叫线性筛法。

欧拉筛法的时间复杂度为 O ( n ) O(n) O(n),本题 n = 1 0 8 n = 10^8 n=108,虽然在理论上超过了 1 0 7 10^7 107,但 1 0 8 10^8 108 以内的合数并没有这么多,因此在实际上不会有那么多的操作次数。

代码

#include <cstdio>
#include <cstring>

using namespace std;

const int N = 1e8 + 10;

int prime[N], n, q;
bool isPrime[N];

void GetPrime() {
	int cnt = 0;
	memset(isPrime, 1, sizeof(isPrime));
	isPrime[0] = 0, isPrime[1] = 0;
	for(int i = 2; i <= n; i++) {
		// 如果 i 依然为 true, 说明当前 i 没有被之前的 i 用 prime[j] 给筛掉,则 i 为素数
		if(isPrime[i])	prime[++cnt] = i;
		// j 循环遍历已有的素数,而且还要确保 i * prime[j] <= n
		for(int j = 1; j <= cnt && i * prime[j] <= n; j++) {
			// i 用 prime[j] 把 i * prime[j] 给筛掉
			// 此时的 prime[j] 是 i * prime[j] 的最小质因数,在下面的例子中可以看出来
			isPrime[i * prime[j]] = 0;
			// 保证线性复杂度的重要条件
			if(i % prime[j] == 0)	break;
		}
	}
}

int main() {
	scanf("%d%d", &n, &q);
	GetPrime();
	while(q--) {
		int k;
		scanf("%d", &k);
		printf("%d\n", prime[k]);
	}
	return 0;
}

复杂度分析:

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( n ) O(n) O(n)

两种方法对比

求 20 以内的素数,筛掉 20 以内的合数

埃氏筛法

i 的值质数表筛去的数
22、3、4、5、6、7、8、9、104、6、8、10、12、14、16、18、20
33、4、5、69、12、15、18
4//
5//
6//
7//
8//
9//
10//
11//
12//
13//
14//
15//
16//
17//
18//
19//
20//

欧拉筛法

i 的值质数表筛去的数
224
32、36、9
428
52、310、15
6212
7214
8216
9218
10220
11//
12//
13//
14//
15//
16//
17//
18//
19//
20//

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/358774.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jetpack管理生命周期——Lifecycle

Android Jetpack 对于任何一个产品来说&#xff0c;我们开发中都会面对哪些问题&#xff1f;如&#xff1a;产品交互、用户体验、代码结构、数据获取、数据存储、网络优化、任务调度等等&#xff0c;虽然在现在的阶段这些问题已经有了很好的解决和优化&#xff0c;也有很多大神…

堆球问题,开普勒猜想(格密码相关)

目录 一. 介绍 二. 历史进展分析 三.2维下的堆球问题 四. 3维下的堆球问题 五. 8维与24维下的堆球问题 总结 一. 介绍 堆球问题又叫堆球理论、最密堆积、球填充&#xff0c;英文为The Theory Of Sphere Packings。 堆球问题的本质就是填充一堆大小相同的球。要求这些球…

FANUC机器人通过KAREL程序实现与PLC位置坐标通信的具体方法示例

FANUC机器人通过KAREL程序实现与PLC位置坐标通信的具体方法示例 在通信IO点位数量足够的情况下,可以使用机器人的IO点传输位置数据,这里以传输机器人的实时位置为例进行说明。 基本流程如下图所示: 基本步骤可参考如下: 首先确认机器人控制柜已经安装了总线通信软件(例如…

CMMI高效实施的5大注意事项

1、明确CMMI实施目标及范围 CMMI在实施过程中&#xff0c;需要根据组织的实际情况&#xff0c;确定CMMI的实施目标和范围&#xff0c;制定实施的计划表&#xff0c;为后续组织过程改进提供明确的方向。 CMMI高效实施注意事项&#xff1a;实施目标及范围的确定​ 2、建立…

虹科新闻 | 虹科与b-plus正式建立合作伙伴关系,共同致力于用于ADAS/AD系统开发的VV测量解决方案

虹科b-plus 携手共创未来&#xff01; 近期&#xff0c;虹科与德国b-plus正式建立合作伙伴关系。未来&#xff0c;虹科与b-plus将共同致力于提供用于ADAS/AD系统开发的V&V测量解决方案。 合作寄语 虹科CEO陈秋苑女士表示&#xff1a;“虹科非常期待与b-plus合作&#x…

线上研讨会报名 | 与龙智、Perforce共探大规模研发中的数字资产管理与版本控制,赢取千元大奖

2023年2月28日下午2:00&#xff0c;加入全球领先的数字资产管理工具厂商Perforce联合中国授权合作伙伴龙智举办的Perforce on Tour网络研讨会&#xff0c;除了与游戏、芯片、虚拟制作行业专家探讨并分享最佳实践外&#xff0c;还可以赢取惊喜大奖&#xff0c;包括千元华为手环、…

语言文件操作

&#x1f331;博客主页&#xff1a;大寄一场. &#x1f331;系列专栏&#xff1a;C语言学习笔记 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 目录 前言 C语言中的文件打开和关闭 文件指针 文件的打开和关闭 fclose 文件的顺序读写 fseek ftell …

Flink-多流转换(Union、Connect、Join)

文章目录多流转换分流基本合流操作联合&#xff08;Union&#xff09;连接&#xff08;Connect&#xff09;基于时间的合流——双流联结&#xff08;Join&#xff09;窗口联结&#xff08;Window Join&#xff09;间隔联结&#xff08;Interval Join&#xff09;窗口同组联结&a…

【Vue3】组件数据懒加载

组件数据懒加载-基本使用 目标&#xff1a;通过useIntersectionObserver优化新鲜好物和人气推荐模块 电商类网站&#xff0c;尤其是首页&#xff0c;内容有好几屏&#xff0c;而如果一上来就加载所有屏的数据&#xff0c;并渲染所有屏的内容会导致首页加载很慢。 数据懒加载&a…

Java面试题--熔断和降级的区别

熔断和降级都是系统自我保护的一种机制&#xff0c;但二者又有所不同&#xff0c;它们的区别主要体现在以下几点&#xff1a; 概念不同 触发条件不同 归属关系不同 1.概念不同 1.1熔断概念 “熔断”一词早期来自股票市场。熔断&#xff08;Circuit Breaker&#xff09;也…

Python3-数据类型转换

有时候&#xff0c;我们需要对数据内置的类型进行转换&#xff0c;数据类型的转换&#xff0c;一般情况下你只需要将数据类型作为函数名即可。 Python 数据类型转换可以分为两种&#xff1a; 隐式类型转换 - 自动完成 显式类型转换 - 需要使用类型函数来转换 隐式类型转换 在…

一图说明 monorepo 落地流程方案

关于 monorepo 初次讨论已有2年载&#xff0c;目前团队已经沉淀了成熟的技术方案且经受住了实战考验。所以特梳理相关如下&#xff1a; 也算是关于之前发起的 monorepo–依赖 的解答篇。 上图为目前团队贡献的主流程&#xff1a;① 本地开发 > ② 提交Git仓库 > ③ 触发…

网络安全高级攻击

对分类器的高层次攻击可以分为以下三种类型&#xff1a;对抗性输入&#xff1a;这是专门设计的输入&#xff0c;旨在确保被误分类&#xff0c;以躲避检测。对抗性输入包含专门用来躲避防病毒程序的恶意文档和试图逃避垃圾邮件过滤器的电子邮件。数据中毒攻击&#xff1a;这涉及…

一种改善调制宽带变换器的有意混叠方法(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

【数组与链表算法】矩阵算法在程序中常见的简单应用 | C++

第二十三章 矩阵算法 目录 第二十三章 矩阵算法 ●前言 ●矩阵算法与深度学习 ●一、矩阵相加 ●二、矩阵相乘 ●三、矩阵转置 ●四、稀疏矩阵 ●总结 前言 数组与链表都是相当重要的结构化数据类型&#xff0c;也都是典型线性表的应用。线性表用于计算机中的数据存储结构…

SpringCloud-学习笔记(五)nacos集群环境搭建

参考视频 集群搭建步骤 搭建MySQL集群并初始化数据库表 下载解压nacos 修改集群配置&#xff08;节点信息&#xff09;、数据库配置 分别启动多个nacos节点 nginx反向代理 安装数据库 官方的建议是使用MySQL组词给模式的高可用集群&#xff0c;这里为了方便演示&#xff0c;仅…

【大厂高频必刷真题100题】《有序矩阵中第 K 小的元素》 真题练习第27题 持续更新~

有序矩阵中第 K 小的元素 给你一个 n x n 矩阵 matrix ,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。 请注意,它是 排序后 的第 k 小元素,而不是第 k 个 不同 的元素。 你必须找到一个内存复杂度优于 O(n^2) 的解决方案。 示例 1: 输入:matrix = [[1,5,9…

makefile编写

文章目录什么是编译器GCC 编译器编写makefile什么是编译器 C语言代码由固定的词汇按照固定的格式组织起来&#xff0c;简单直观&#xff0c;程序员容易识别和理解&#xff0c;但是对于CPU&#xff0c;C语言代码就是天书&#xff0c;根本不认识&#xff0c;CPU只认识几百个二进…

Windows 免安装版mysql,快速配置教程

简单步骤 下载并解压mysql压缩包&#xff0c;把 “<mysql根目录>/bin” 路径添加到系统环境变量path中命令行执行 mysqld --initialize --console&#xff0c;初始化data目录&#xff08;数据库表文件默认存放在" <mysql安装根目录>/data "目录下&#…

JavaScript Web API 来构建你不了解的网站

随着技术的日新月异&#xff0c;为开发人员提供了令人难以置信的新工具和API。 但据了解&#xff0c;在100 多个 API中&#xff0c;只有5%被开发人员积极使用。 随着技术的日新月异&#xff0c;为开发人员提供了令人难以置信的新工具和API。但据了解&#xff0c;在100 多个 A…