数学知识--(质数,约数)

本文用于个人算法竞赛学习,仅供参考

目录

一.质数的判定

二.分解质因数

三.质数筛

1.朴素筛法

 2.埃氏筛法

3.线性筛法

 四.约数

1.求一个数的所有约数

2.约数个数和约数之和

3.欧几里得算法(辗转相除法)-- 求最大公约数


一.质数的判定

质数:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的数。常见的质数有2, 3, 5, 7, 11等。质数也被称为素数。

试除法:时间复杂度:O(n^ 1/2)

bool is_prime(int n)
{if (n < 2)return false;for (int i = 2; i <= n / i; i++) //如果存在 a ÷ b = c , 那么就有 a ÷ c = b; {if (n % i == 0){return false;}}return true;
}

二.分解质因数

 

试除法:时间复杂度:O(n^ 1/2)

//存放分解后质数的个数
unordered_map<int, int> primes;void divide(int n)
{//从2开始试除for (int i = 2; i <= n / i; i++)// i^2 <= n{//合数进不来,因为被前面的质数约去了if (n % i == 0){while (n % i == 0){primes[i]++;n /= i;}}}if (n > 1)primes[n]++;
}int main()
{divide(84);for (auto prime: primes){cout << prime.first << ':' << prime.second << endl;}return 0;
}

三.质数筛

问题:给定一个n,筛出2~n的所有质数

1.朴素筛法

假设一个数n,它的因数有a, 那么n的因数a一定小于n,所以只需要通过a的倍数就能筛掉n,所以朴素筛法就是从2到n筛掉它们的倍数,最后剩下的就是质数。

时间复杂度:N(1 + 1/2 + 1/3 + ... + 1/n) = N*lnN,  O(N*lnN);

 可以发现同一个数可能会被筛掉多次,当样本个数非常多的时候是非常浪费时间的,要如何优化降低对一个数筛的次数呢?

 2.埃氏筛法

埃氏筛法是对上面朴素筛法的优化,只筛掉质数的倍数,来减少筛掉同一个数的次数。

埃氏筛法(Sieve of Eratosthenes)是一种用来找出一定范围内所有素数的算法。其基本思想是从2开始,不断地将质数的倍数标记为非质数,最终剩下的即为质数。

 筛掉4的倍数时,其实在筛掉2的倍数时就筛掉了,因为4是2的倍数,4的倍数也是2的倍数,所以4就没必要再去筛掉它的倍数了;对于一个合数,总会有它的质数代替它来筛掉它的倍数。

质数定理指出,小于给定数n的质数个数约为 n / ln(n)。

优化后时间O(N*loglogN)

const int N = 100;
int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉void get_primes(int n)
{for (int i = 2; i <= n; i++){if (st[i]) continue;primes[cnt++] = i;for (int j = i + i; j <= n; j += i)st[j] = true;}
}

 

 我们发现还是存在对同一个数多次筛掉的情况,如12被2和3筛掉两次,还能再优化吗?

3.线性筛法

线性筛法是一种在O(n)的复杂度情况下,筛选出2~n的所有质数。
它的原理是,从2开始,每次找到一个最小的质数,然后把它的倍数都标记为非质数,即每个数合数只会被它的最小质因数筛掉。

比如上面的埃氏筛法,12会被2和3筛两次,线性筛法只会通过12的最小的质数2来筛掉。

最外层for循环遍历2~n,primes保存2~i的质数,内层for循环从小枚举质数

1.对于   primes[j] <= n / i;

如果i是合数,会走到 if (i % primes[j] == 0) break  结束掉

如果i是质数,会走到 primes[j] == i 后结束掉

所以不用担心存在越界问题 

2.对于  if (i % primes[j] == 0) break;

若 i % primes[j] != 0, primes[j]一定小于i的最小质因子,primes[j] 一定是primes[j] * i 的最小质因子,因为primes从小到大枚举,且primes[j] 小于i

若i % primes[j] == 0,primes[j] 一定是i的最小质因子,primes[j] 一定是primes[j] * i 的最小质因子,因为primes从小到大枚举,且primes[j] 小于i

如果i % primes[j] == 0,就应该break了,为什么?

已知i % primes[j] == 0,就说明i是合数,i已经再前面通过k * primes[j] 筛掉了;

假设我们没有break,走到primes[j + 1], 会有 i * primes[j + 1], 代入得 k * primes[j] * primes[j + 1],很明显primes[j] < primes[j + 1], 说明一个数已经被primes[j] 筛掉过了,再通过primes[j]筛就重复了。

3.对于每一个合数x,一定会被筛掉,假设x的最小质因子为p,当i 遍历到x / p时,x一定会被筛掉。

4.每一个合数都会被它的最小质数筛掉,说明每个数只会被筛一次,所以是线性的,时间复杂度是O(n)。

int primes[N], cnt;     // primes[]存储所有素数
bool st[N];         // st[x]存储x是否被筛掉void get_primes(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[primes[j] * i] = true;if (i % primes[j] == 0) break;}}
}

 四.约数

1.求一个数的所有约数

试除法:枚举 i <= n / i, 看i 是否是约数

vector<int> get_divisors(int n)
{vector<int> result;for (int i = 2; i <= n / i; i++){if (n % i == 0){result.push_back(i);//避免加入同一个数if (n / i != i)result.push_back(n / i);}}sort(result.begin(), result.end());return result;
}

2.约数个数和约数之和

给定一个数N,求N的约数个数

将N进行质因数分解p,有N = p1^c1 * p2^c2 * ... *pk^ck
对于每个质数p,c可以取0~c,则约数个数: (c1 + 1) * (c2 + 1) * ... * (ck + 1)
约数之和: (p1^0 + p1^1 + ... + p1^c1) * ... * (pk^0 + pk^1 + ... + pk^ck)

 思路:

由N = p1^c1 * p2^c2 * ... *pk^ck,约数和为(p1^0 + p1^1 + ... + p1^c1) * ... * (pk^0 + pk^1 + ... + pk^ck)

p比较好求,直接分解质因数就行,问题是(pk^0 + pk^1 + ... + pk^ck)要怎么求?

假设 t = 1,存在操作 t = p * t + 1;

则有t = p * 1 + 1 = p + 1

t = p * (p + 1) + 1 = p^2 + p + 1

t = p * (p^2 + p + 1) + 1 = p^3 + p^2 + p^1 + 1

……

typedef long long LL;
int mod = 1e9 + 7;int main()
{unordered_map<int, int> primes;int n;cin >> n;while (n--){int a;cin >> a;//对每个数进行质因数分解for (int i = 2; i <= a / i; i++){if (a % i == 0){primes[i]++;a /= i;}}if (a > 1)primes[a]++;}LL result = 1;for (auto prime : primes){LL t = 1;int a = prime.first, b = prime.second;while (b--){t = (t * a + 1) % mod;}result = result * t % mod;}cout << result << endl;return 0;
}

常见模运算

(a * b) mod c = ((a mod c) * (b mod c)) mod c
(a + b) mod c = ((a mod c) + (b mod c)) mod c
(a - b) mod c = ((a mod c) - (b mod c)) mod c
(a ^ b) mod c = ((a mod c) ^ b) mod c
(a / b) mod c != ((a mod c) / (b mod c)) mod c除法的模运算不满足这样的等式

3.欧几里得算法(辗转相除法)-- 求最大公约数

gcd(a, b) = gcd(b, a mod b);

gcd代表最大公约数

int gcd(int a, int b)
{//if (a < b) swap(a, b);//这一步不需要,因为会自己调整,比如gcd(6,16),下一次递归就变成了gcd(16,6)return b ? gcd(b, a % b) : a;
}

 

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

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

相关文章

新型智慧城市大数据解决方案(附下载)

随着云计算、大数据、移动互联网等技术的发展&#xff0c;由城市运行产生的交通、环境、市政、商业等各领域数据量巨大&#xff0c;这些数据经过合理的分析挖掘可产生大量传统数据不能反映的城市运行信息&#xff0c;已成为智慧城市的重要资产。 在大数据时代&#xff0c;数据信…

理解main方法的语法

由于JVM需要调用类的main()方法&#xff0c;所以该方法的访问权限必须是public&#xff0c;又因为JVM在执行main()方法时不必创建对象&#xff0c;所以该方法必须是static的&#xff0c;该方法接收一个String类型的数组参数&#xff0c;该数组中保存执行Java命令时传递给所运行…

问题解决:写CSDN博文时图片大小不适应,不清晰,没法排版

项目环境&#xff1a; Window10&#xff0c;Edge123.0.2420.65 问题描述&#xff1a; 当我在CSDN写博文的时候&#xff0c;会经常插入一些图片&#xff0c;但有时候我插入的图片太大了&#xff0c;影响了整体排版。 比如我加入了一张图片&#xff0c;就变成了下面这个样子&…

释放 ChatGPT4 的威力

原文&#xff1a;Unleashing the Power of ChatGPT-4: Strategies for Building a Personal Income Stream 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 I. 介绍 在当今快速发展的数字领域中&#xff0c;人工智能&#xff08;AI&#xff09;已经成为无数行业的重要…

Kubernetes探索-Deployment面试

1. 简述Deployment的升级策略 在Deployment的定义中&#xff0c;可以通过spec.strategy指定Pod更新的策略&#xff0c;目前支持两种策略&#xff1a;Recreate&#xff08;重建&#xff09;和RollingUpdate&#xff08;滚动更新&#xff09;&#xff0c;默认值为RollingUpdate。…

PEFT-LISA

LISA是LoRA的简化版&#xff0c;但其抓住了LoRA微调的核心&#xff0c;即LoRA侧重更新LLM的底层embedding和顶层head。 根据上述现象&#xff0c;LISA提出两点改进&#xff1a; 始终更新LLM的底层embedding和顶层head随机更新中间层的hidden state 实验结果 显存占用 毕竟模型…

RAMS (Mesoscale Model System) 和 WRF 区别

历史和发展&#xff1a; RAMS&#xff1a;RAMS 最早于1970年代由美国科罗拉多州立大学开发&#xff0c;并在之后几十年不断发展壮大。它是最早用于模拟地区尺度大气动力学、热力学和降水过程的模型之一。WRF&#xff1a;WRF 是由美国国家大气研究中心&#xff08;NCAR&#xff…

openstack云计算(一)————openstack安装教程,创建空白虚拟机,虚拟机的环境准备

1、创建空白虚拟机 需要注意的步骤会截图一下&#xff0c;其它的基本都是下一步&#xff0c;默认的即可 ----------------------------------------------------------- 2、在所建的空白虚拟机上安装CentOS 7操作系统 &#xff08;1&#xff09;、在安装CentOS 7的启动界面中…

RuoYi-Vue若依框架-集成mybatis-plus报错Unknown column ‘search_value‘ in ‘field list‘

报错信息 ### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Unknown column search_value in field list ### The error may exist in com/ruoyi/sales/mapper/ZcSpecificationsMapper.java (best guess) ### The error may involve defaultParameter…

C++之STL的algorithm(6)之排序算法(sort、merge)整理

C之STL的algorithm&#xff08;6&#xff09;之排序算法&#xff08;sort、merge&#xff09;整理 注&#xff1a;整理一些突然学到的C知识&#xff0c;随时mark一下 例如&#xff1a;忘记的关键字用法&#xff0c;新关键字&#xff0c;新数据结构 C 的排序算法整理 C之STL的al…

Oracle数据库——分组函数四

12.1什么是分组函数 分组函数作用于一组数据,并对一组数据返回一个值。例如求平均数,最大值等等。 1.组函数类型 AVG :求平均数COUNT :COUNT(expr) 返回expr不为空的记录总数。 MAX 求最大值MIN

【简单讲解下WebSocket】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

Vue探索之Vue2.x源码分析(一)

一.响应式数据之数组的处理 <template><div><ul><li v-for"(item, index) in items" :key"index">{{ item }}<button click"removeItem(index)">Remove</button></li></ul><input v-model&…

Python卷积网络车牌识别系统(V2.0)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

基于单片机的无线红外报警系统

**单片机设计介绍&#xff0c;基于单片机的无线红外报警系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的无线红外报警系统是一种结合了单片机控制技术和无线红外传感技术的安防系统。该系统通过无线红外传感器实…

SpringBoot -- 外部化配置

我们如果要对普通程序的jar包更改配置&#xff0c;那么我们需要对jar包解压&#xff0c;并在其中的配置文件中更改配置参数&#xff0c;然后再打包并重新运行。可以看到过程比较繁琐&#xff0c;SpringBoot也注意到了这个问题&#xff0c;其可以通过外部配置文件更新配置。 我…

鸿蒙系统前端:构建智能互联新时代的界面之美

随着华为鸿蒙系统的推出&#xff0c;前端技术也迎来了新的挑战与机遇。鸿蒙系统&#xff0c;作为华为自主研发的分布式操作系统&#xff0c;旨在打通各类智能设备&#xff0c;为用户提供一个无缝的智能互联体验。在这个宏大的愿景下&#xff0c;鸿蒙系统的前端设计显得尤为重要…

Java作业练习_第六周作业多态性(小白学习记录,仅供参考,有错指出)

题目排序&#xff08;点击直达&#xff09; 第一题第二题第三题第四题第五题第六题第七题第八题免责声明 第一题 写出下列程序的运行结果&#xff1a; package com.cxl.ch5.demo5; public class Base {int m0;public int getM(){return m;} } package com.cxl.ch5.demo5;publ…

第18章 JDK8-17新特性

1. Java版本迭代概述 1.1 发布特点&#xff08;小步快跑&#xff0c;快速迭代&#xff09; 发行版本发行时间备注Java 1.01996.01.23Sun公司发布了Java的第一个开发工具包Java 5.02004.09.30①版本号从1.4直接更新至5.0&#xff1b;②平台更名为JavaSE、JavaEE、JavaMEJava 8…

复杂度的讲解

1.算法效率 如何衡量一个算法的好坏&#xff1f;从两个维度&#xff0c;时间和空间&#xff08;算法运行的快慢&#xff0c;消耗的空间大不大&#xff09;。因为计算机硬件领域的高速发展&#xff0c;如今计算机的存储量已经达到了一个很高的程度&#xff0c;所以现在我们一般…