当前位置: 首页 > news >正文

NOI大纲——普及组——素数筛法

素数筛的进化史

1.最为基础的筛法——试除法

时间复杂度 O ( n 2 ) O(n^2) O(n2)

int a[10000],tot=0,n;
for (int i=2;i<=n;i++){bool flag=false;for (int j=2;j<i;j++){if (i%j==0)flag=true;}if (flag==false){a[tot]=i;tot++;}
}
for (int i=0;i<tot;i++){cout<<a[i]<<" ";
}
//筛1到n的质数

2.试除法的优化

时间复杂度 O ( n × n ) O(n\times \sqrt{n}) O(n×n )

int a[10000],tot=0,n;
for (int i=2;i<=n;i++){bool flag=false;for (int j=2;j<=sqrt(i);j++){if (i%j==0)flag=true;}if (flag==false){a[tot]=i;tot++;}
}
for (int i=0;i<tot;i++){cout<<a[i]<<" ";
}
//筛1到n的质数

埃拉托色尼筛法(Eratosthenes Sieve)

埃拉托色尼筛法是一种古老且高效的算法,用于找出某个范围内所有的素数。它的工作原理基于反复标记出合数(即非素数)。其核心思想如下:

  1. 设定一个范围,例如从2到某个整数n。
  2. 从最小的素数2开始,标记2的所有倍数为合数(非素数)。
  3. 找到下一个未被标记的数,它是下一个素数,然后标记这个素数的所有倍数。
  4. 重复步骤3,直到到达范围的尽头。

下面是埃拉托色尼筛法的详细步骤及代码实现:

步骤详解

  1. 初始化数组:创建一个布尔数组isPrime,其大小为n+1,所有元素初始化为true。这个数组用于标记是否为素数。
  2. 标记合数:从2开始,对于每一个isPrime为true的数i,标记i的所有倍数为false。
  3. 终止条件:i的值不超过 n \sqrt{n} n 。因为如果i的值超过 n \sqrt{n} n ,i的倍数中最小的一个已经大于n,因此没有必要继续标记。

代码实现

int a[100000], tot = 0; // 存储素数的数组和计数器
bool ais[100000]; // 标记数组for (int i = 2; i <= n; i++) { // 从2开始遍历到nif (ais[i] == 0) { // 如果i没有被标记为合数a[tot++] = i; // 将i存入素数数组for (int j = 2; j < n && j * i <= n; j++) { // 从2开始标记i的倍数ais[i * j] = 1; // 标记i的倍数为合数}}
}for (int i = 0; i < tot; i++) { // 输出所有素数cout << a[i] << " ";
}

示例

假设我们要找出30以内的所有素数:

  1. 初始化:isPrime数组为[true, true, true, …, true],长度为31。
  2. 从2开始,标记2的倍数:4, 6, 8, 10, …, 30都标记为false。
  3. 下一个未标记的数是3,标记3的倍数:6, 9, 12, 15, …, 30都标记为false。
  4. 下一个未标记的数是5,标记5的倍数:10, 15, 20, 25, 30都标记为false。
  5. 继续下去,直到√30≈5.48。

结果:2, 3, 5, 7, 11, 13, 17, 19, 23, 29为素数。

欧拉筛(Euler’s Sieve)

欧拉筛法是埃拉托色尼筛法的一种改进版本,它在标记合数时避免了重复工作,因此效率更高。欧拉筛法利用了以下性质:

  1. 每个合数都可以表示为若干素数的乘积。
  2. 对于每个素数p,标记其倍数时,只需从它开始标记,不需要重复标记已经被其他素数标记过的数。

步骤详解

  1. 初始化数组:与埃拉托色尼筛法类似,初始化一个布尔数组isPrime和一个存储素数的数组a。
  2. 标记合数:对于每一个数i,如果它是素数,将其存入数组a,然后标记其所有的合数。
  3. 终止条件:当i的值达到n时停止。

代码实现

const int MAXN = 100000; // 定义常量,最大范围
int a[MAXN], tot = 0; // 存储素数的数组和计数器
bool isPrime[MAXN]; // 标记数组void eulerSieve(int n) {fill(isPrime, isPrime + n + 1, true); // 初始化标记数组,所有元素设为trueisPrime[0] = isPrime[1] = false; // 0和1不是素数for (int i = 2; i <= n; i++) { // 从2开始遍历到nif (isPrime[i]) { // 如果i是素数a[tot++] = i; // 将i存入素数数组}for (int j = 0; j < tot && a[j] * i <= n; j++) { // 遍历所有已存入的素数isPrime[a[j] * i] = false; // 标记a[j]和i的乘积为合数if (i % a[j] == 0) break; // 如果i是a[j]的倍数,停止标记}}// 输出所有素数for (int i = 0; i < tot; i++) {cout << a[i] << " ";}cout << endl;
}

示例

假设我们要找出30以内的所有素数:

  1. 初始化:isPrime数组为[true, true, true, …, true],长度为31。
  2. 从2开始,2是素数,存入数组a,标记2的倍数:4, 6, 8, 10, …, 30都标记为false。
  3. 下一个未标记的数是3,3是素数,存入数组a,标记3的倍数:6, 9, 12, 15, …, 30都标记为false。
  4. 继续下去,直到i达到30。

结果:2, 3, 5, 7, 11, 13, 17, 19, 23, 29为素数。

两种算法的比较

  • 效率:欧拉筛法避免了重复标记合数,因此在实际应用中效率比埃拉托色尼筛法更高。
  • 复杂度:两种算法的时间复杂度都是O(n log log n),但欧拉筛法的常数项更小。
  • 空间使用:两种算法都需要一个大小为n+1的布尔数组,因此在空间使用上没有显著差别。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • CentOS搭建Apache服务器
  • 【深度学习】yolov8-det目标检测训练,拼接图的分割复原
  • 网络安全防御【IPsec VPN搭建】
  • 环信+亚马逊云科技服务:助力出海AI社交应用扬帆起航
  • Python3网络爬虫开发实战(3)网页数据的解析提取
  • SSIS_SQLITE
  • 【数据结构--查找】
  • 【反证法】932. 漂亮数组
  • 使用php adodb5连接人大金仓数据库
  • 揭秘Django与Neo4j:构建智能知识图谱的终极指南
  • Adam 和 RMSprop优化算法
  • 每日任务:HTTP状态码详解及强缓存与协商缓存的区别
  • EXO-chatgpt_api 解释
  • 常见的文心一言的指令
  • 力扣面试题(三)
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • Android 控件背景颜色处理
  • Computed property XXX was assigned to but it has no setter
  • cookie和session
  • css布局,左右固定中间自适应实现
  • gulp 教程
  • isset在php5.6-和php7.0+的一些差异
  • js操作时间(持续更新)
  • PHP 7 修改了什么呢 -- 2
  • React+TypeScript入门
  • 从零开始的无人驾驶 1
  • 从输入URL到页面加载发生了什么
  • 函数式编程与面向对象编程[4]:Scala的类型关联Type Alias
  • 开源SQL-on-Hadoop系统一览
  • 入职第二天:使用koa搭建node server是种怎样的体验
  • 实现菜单下拉伸展折叠效果demo
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 详解NodeJs流之一
  • 新书推荐|Windows黑客编程技术详解
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ​Redis 实现计数器和限速器的
  • # 飞书APP集成平台-数字化落地
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (二开)Flink 修改源码拓展 SQL 语法
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (数据大屏)(Hadoop)基于SSM框架的学院校友管理系统的设计与实现+文档
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (转载)CentOS查看系统信息|CentOS查看命令
  • .form文件_一篇文章学会文件上传
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net 高效开发之不可错过的实用工具
  • .NET 药厂业务系统 CPU爆高分析
  • .考试倒计时43天!来提分啦!
  • @Data注解的作用
  • [.net]官方水晶报表的使用以演示下载