0x31 质数

0x31 质数

定义:

若一个正整数无法被除了1和它自身之外的任何自然数整除,则称该数为质数(或素数),否则则称该正整数为合数。

在整个自然数集合中,质数的数量不多,分布比较稀疏,对于一个足够大的整数N,不超过 N N N的质数大约有 N / l n N N/lnN N/lnN个,即 l n N lnN lnN个数中大约有一个质数。

1.质数的判定

试除法

若一个正整数 N N N为合数,则存在一个能整除 N N N的整数 T T T,其中 2 ≤ T ≤ N 2\leq T \leq \sqrt{N} 2TN

我们只需扫描 2 ∼ N 2\sim \sqrt{N} 2N 之间所有的整数,依次检查它们能否整除 N N N,若都不能整除,则 N N N是质数,否则 N N N是合数。试除法的时间复杂度是 O ( N ) O(\sqrt{N}) O(N )。当然我们需要特判0和1这两个数,它们既不是质数也不是合数。

bool is_prime(int n)
{if(n<2)return false;for(int i=2;i<=sqrt(n);++i)if(n%i==0)return false;return true;
}

“试除法”作为最简单也最经典的确定性算法,是我们在算法竞赛中通常会使用的方法。有一些效率更高的随机性算法,例如“Miller-Robbin”等,有较小的概率把合数误判定为质数,但多次判定合起来错误概率趋近于0。

2.质数的筛选

给定一个整数N,求出 1 ∼ N 1\sim N 1N之间所有的质数,称为质数的筛选问题。

Eratosthenes筛法(埃式筛法)

Eratosthenes筛法基于这样的想法:任意整数 x x x的倍数 2 x 2x 2x 3 x 3x 3x,…都不是质数。

我们可以从2开始,由小到大扫描每个数 x x x,然后把它的倍数 2 x 2x 2x 3 x 3x 3x,…, ⌊ N / x ⌋ ∗ x \lfloor N/x \rfloor *x N/xx标记为合数。当扫描到一个数,若它未被标记,则说明它不能被 2 ∼ x − 1 2\sim x-1 2x1之间的任何数整除,该数就是质数。

Eratosthenes筛法如下:

在这里插入图片描述

我们发现,2和3都会把6标记为合数。实际上,小于 x 2 x^2 x2 x x x的倍数在扫描更小的数时就已经被标记过了。因此,我们可以对Eratosthenes筛法进行优化,对于每个数 x x x,我们只需要从 x 2 x^2 x2开始,把 x 2 x^2 x2 ( x + 1 ) ∗ x (x+1)*x (x+1)x ( x + 2 ) ∗ x (x+2)*x (x+2)x,…, ⌊ N / x ⌋ ∗ x \lfloor N/x \rfloor *x N/xx标记为合数即可。

void prime(int n)
{memset(v,0,sizeof(v)); //合数标记,全都标记为质数for(int i=2;i<=n;++i){if(v[i]) continue;cout<<i<<endl; //i是质数for(int j=i;j<=n/i;++j)v[i*j]=1;}
}

Eratosthenes筛法的时间复杂度为 O ( ∑ 质数 p ≤ N N P ) = O ( N l o g l o g n ) O(\sum_{质数p\leq N} \frac{N}{P})=O(Nloglogn) O(质数pNPN)=O(Nloglogn)。该算法实现简单,效率已经非常接近线性,是算法竞赛中最常用的质数筛法。

Euler筛法(欧拉筛法/线性筛法)

即使在优化后(从 x 2 x^2 x2开始),Eratosthenes筛法仍然会重复标记合数。例如12既会被2标记又会被3标记。其根本原因是我们没有确定出唯一的产生12的方式。

线性筛法通过“从小到大累计质因子”的方式标记每一个合数,即让12只有3*2*2一种方式产生。设数组 v v v记录每个数的最小质因子,我们按照以下步骤维护 v v v

1.依次考虑 2 ∼ N 2\sim N 2N中的每个数 i i i

2.若 v [ i ] = i v[i]=i v[i]=i,说明 i i i是质数,把它保存下来。

3.扫描不大于 v [ i ] v[i] v[i]的每个质数 p p p,令 v [ i ∗ p ] = p v[i*p]=p v[ip]=p。也就是在 i i i的基础上累积一个质因子 p p p。因为 p ≤ v [ i ] p\leq v[i] pv[i],所以 p p p就是合数 i ∗ p i*p ip的最小质因数。

在这里插入图片描述

每个合数只会被它的最小质因数 p p p筛一次,时间复杂度为 O ( n ) O(n) O(n)

int v[MAX_N],prime[MAX_N];
int m=0; //质数数量
void primes(int n)
{memset(v,0,sizeof(v)); //最小质因子for(int i=2;i<=n;++i){if(v[i]==0)v[i]=i,prime[++m]=i;//给当前的i乘上一个质因子for(int j=1;j<=m;++j){//i有比prime[j]更小的质因子或超出n的范围,停止循环if(prime[j]>v[i]||prime[j]*i>n)break;//prime[j]是合数prime[j]*i的最小质因子v[prime[j]*i]=prime[j];}}
}

我们也可以直接把 v v v数组改为 i s _ p r i m e is\_prime is_prime数组,判断这个数是不是质数。

bool is_prime[MAX_N];
int prime[MAX_N];
int m;
void prime(int n)
{for(int i=2;i<=n;++i)is_prime[i]=true;for(int i=2;i<=n;++i){if(is_prime[i])prime[++m]=i;for(int j=1;j<=m&&i*prime[j]<=n;++j){is_prime[i*prime[j]]=false;//如果i整除prime[j],则说明prime[j]正好是i*prime[j]最小质因数//后面的prime[j+1]大于最小质因数,退出循环if(i%prime[j]==0)break;}}
}

但是这个写法的实际运行时间可能与优化后的埃式筛法近似,因为存在低效的取模运算。

3.质因数分解

算术基本定理

任何一个大于1的正整数都能唯一分解为有限个质数的乘积,可写作:
N = p 1 c 1 p 2 c 2 . . . p m c m N=p_1^{c_1}p_2^{c_2}...p_m^{c_m} N=p1c1p2c2...pmcm
其中 c i c_i ci都是正整数, p i p_i pi都是质数,且满足 p 1 < p 2 < . . . < p m p_1<p_2<...<p_m p1<p2<...<pm

试除法

结合质数判定的“试除法”和质数筛选的“Eratosthenes筛法”,我们可以扫描 2 ∼ ⌊ N ⌋ 2\sim \lfloor \sqrt{N} \rfloor 2N 的每个数 d d d,若 d d d能整除 N N N,则从 N N N中除掉所有因子 d d d,同时累计除去的 d d d的个数。时间复杂度为 O ( N ) O(\sqrt{N}) O(N )

void divide(int n)
{m=0;for(int i=2;i<=sqrt(n);++i){if(n%i==0)//i是质数{p[++m]=i,c[m]=0;while(n%i)n/=i,c[m]++;}}if(n>1) //n是质数p[++m]=n,c[m]=1;
}

Pollard's Rho”算法是一个比“试除法”效率更高的质因数分解方法。

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

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

相关文章

动态规划——OJ题(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、第N个泰波那契数1、题目讲解2、思路讲解3、代码实现 二、三步问题1、题目讲解2、思路讲解…

拖拽属性 draggable

H5 新增的属性 draggable&#xff0c;它能够给与一切的 html 元素拖动的效果。 拖拽元素 属性为 draggable"true" 的元素&#xff0c;可拖动&#xff0c;且拖动时鼠标变为禁用图标 ps: 直接写 draggable 可能无效 ondragstart 开始拖拽时触发&#xff08;按下鼠标…

ARM架构简析

全局与局量等知识 断电后&#xff0c;程序以及数据都在FLASH中。 断电后&#xff0c;内存中就没有变量了。 程序在烧在FLASH中的&#xff1b; 程序运行的时候&#xff0c;全局变量的初始值&#xff0c;必然是从FLAASH中的来的&#xff1a; 初始化全局变量的过程&#xff1a;…

pytorch和pytorchvision安装

参考https://blog.csdn.net/2301_76863102/article/details/129369549 https://blog.csdn.net/weixin_43798572/article/details/123122477 查看我的版本 右键&#xff0c;nvivdia控制面板&#xff0c;帮助&#xff0c;系统信息 驱动程序版本号为528.49 更新很快的 CUDA版本…

cpp:1:10: fatal error: opencv2/core.hpp: 没有那个文件或目录

前言&#xff1a; 我按照官网方法安装了opencv&#xff0c;运行的也是官网的测试代码&#xff1a; #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> using namespace cv; int main() {printf("hello world")return 0; } 半解决&#xff…

k8s - container

1、容器的生命周期&#xff1a; (1) 简介&#xff1a; Kubernetes 会跟踪 Pod 中每个容器的状态&#xff0c;就像它跟踪 Pod 总体上的阶段一样。 可以使用容器生命周期回调&#xff0c;在容器生命周期中的特定状态点触发事件。 ● 容器生命周期回调&#xff1a; 在容器的生…

数据结构之<图>的介绍

图&#xff08;Graph&#xff09;的概念&#xff1a; 在数据结构中&#xff0c;图是由节点&#xff08;顶点&#xff09;和边组成的非线性数据结构。图用于表示不同对象之间的关系&#xff0c;其中节点表示对象&#xff0c;边表示对象之间的连接或关系。 1.图的基本组成元素&a…

人生感悟 | 当前经济形势,给25~35岁的年轻人一点建议

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 这两年经济情况怎么样呢&#xff1f;相信大家都有自己的感觉。 且不说网上看到的“裁员裁到大动脉”“设计院欠薪”等各种新闻。 说自己和家人的亲身经历吧&#xff0c;这两年经历了被拖欠工资、公司缩编、换工作、公…

Vue中插槽的使用

目录 一、默认插槽 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;代码展示 &#xff08;3&#xff09;后备内容 二、具名插槽 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;代码展示 三、作用域插槽 &#xff08;1&#xff09;概念 &#xff0…

一个 tomcat 下如何部署多个项目?附详细步骤

一个tomcat下如何部署多个项目&#xff1f;Linux跟windows系统下的步骤都差不多&#xff0c;以下linux系统下部署为例。windows系统下部署同理。 1 不修改端口&#xff0c;部署多个项目 清楚tomcat目录结构的应该都知道&#xff0c;项目包是放在webapps目录下的&#xff0c;那…

vue2 echarts不同角色多个类型数据的柱状图

前端代码&#xff1a; 先按照echarts插件。在页面里引用 import * as echarts from "echarts";设置div <div style"width:100%;height:250px;margin-top: 4px;" id"addressChart"></div>方法: addressEcharts() {const option {g…

RabbitMQ搭建集群环境、配置镜像集群、负载均衡

RabbitMQ集群搭建 Linux安装RabbitMQ下载安装基本操作命令开启管理界面及配置 RabbitMQ集群搭建确定rabbitmq安装目录启动第一个节点启动第二个节点停止命令创建集群查看集群集群管理 RabbitMQ镜像集群配置启用HA策略创建一个镜像队列测试镜像队列 负载均衡-HAProxy安装HAProxy…

【精选】计算机网络教程(第3章数据链路层)

目录 前言 第3章数据链路层 1、差错检测&#xff08;CRC&#xff09; 2、点对点协议&#xff08;了解应用场景&#xff09; 3、什么是碰撞域&#xff0c;什么是广播域 碰撞域&#xff08;Collision Domain&#xff09;&#xff1a; 广播域&#xff08;Broadcast Domain&a…

计算机组成原理学习(输入输出系统)

目录 输入输出系统&#xff08;i/o系统&#xff09; 一.现代计算机的结构 二.常见的&#xff08;I/O设备或者是外部设备&#xff09; ​ 三.主机如何与I/O设备进行交互 四.I/O控制方式简介 五.I/O系统的基本组成 输入输出系统&#xff08;i/o系统&#xff09; 一.现代计算…

一键安装下载3ds Max!别墅还是宫殿?3ds Max助你建造梦幻般的艺术建筑

不再浪费时间在网上寻找3ds Max的安装包了&#xff01;因为你所需要的一切都可以在这里找到&#xff01;作为一款全球领先的3D设计工具&#xff0c;3ds Max为创作者们带来了前所未有的便利和创作灵感。无论是建筑设计、影视特效还是游戏开发&#xff0c;3ds Max都能帮助你实现想…

C++——C++11(1)

时至今日&#xff0c;C标准已经到了C23&#xff0c;但是你要说哪一次提出的标准最经 典&#xff0c;那C11一定会被人提及&#xff0c;C11带来了数量可观的变化&#xff0c;其中包 含了约140个新特性&#xff0c;以及对C03标准中约600个缺陷的修正&#xff0c;这使得 C11更像是从…

一个神奇的Python库:Evidently,机器学习必备

Evidently 是一个面向数据科学家和机器学习工程师的开源 Python 库。它有助于评估、测试和监控从验证到生产的数据和 ML 模型。它适用于表格、文本数据和嵌入。 简介 Evidently 是一个开源的 Python 工具&#xff0c;旨在帮助构建对机器学习模型的监控&#xff0c;以确保它们的…

博客动态校验+静态校验二次开发方式

静态校验&#xff1a; 1&#xff1a;将需要静态校验的参数继承BaseReqeust类重写validate方法&#xff1a; 动态校验&#xff1a; 1&#xff1a;在需要校验的实现类上加&#xff1a; BizValidate注解 2&#xff1a;写一个校验类&#xff0c;方法命名规范为&#xff1a;需要校…

修改npm源码解决服务端渲染环境中localstorage报错read properties of undefined (reading getItem)

现象&#xff1a; 这个问题是直接指向了我使用的第三方库good-storage&#xff0c;这是一个对localStorage/sessionStorage做了简单封装的库&#xff0c;因为项目代码有一个缓存cache.ts有用到 原因分析&#xff1a; 从表象上看是storage对象找不到getItem方法&#xff0c; 但…

Android--Jetpack--数据库Room详解一

人生何须万种愁&#xff0c;千里云烟一笑收 一&#xff0c;定义 Room也是一个ORM框架&#xff0c;它在SQLite上提供了一个抽象层&#xff0c;屏蔽了部分底层的细节&#xff0c;使用对象对数据库进行操作&#xff0c;进行CRUD就像对象调用方法一样的简单。 二&#xff0c;角色介…