数论 - 质数和约数

文章目录

  • 前言
  • 一、质数
    • 1.质数的判定-试除法
    • 2.分解质因子-试除法
    • 3.筛选质数
  • 二、约数
    • 1.求约数-试除法
    • 2.约数的个数
    • 3.约数之和
    • 4.最大公约数-欧几里得算法

前言

本章博客将介绍质数和约数的常用模板,这些题目都比较简单,都可以通过暴力获取答案,但是时间复杂度较高,不符合算法比赛的要求,所以本篇博客介绍的方法都是时间复杂度低效率高的方法,并给出简化复杂度的思路。

质数部分将介绍:质数的判定,分解质因子,筛选质数
约数部分将介绍:求约数,约数的个数,约数之和,最大公约数

一、质数

在大于1的整数中,如果只包含1和本身这两个约数,就被称为质数,或者素数

1.质数的判定-试除法

  • 约数成对出现,如果d|n,则n/d必然也整除n,所以我们枚举的时候只需要枚举前一部分即可,也就是d<=r/d这一部分
  • 不写成d*d<=r是因为防止爆int
  • 不写成d<=sqrt®是因为sqrt效率低
  • 时间复杂度从O(n)降低到了O(sqrt(n))
bool is_prime(int n)
{if(n < 2) return false;for(int i = 2; i <= n / i; i ++ )if(n % i == 0)return false;return true;
}

2.分解质因子-试除法

  • N = P1a1 * P2a2 * P3a3 * …… * Pkak(P1到k均为质数)
  • 从小到大依次枚举,这个不需要考虑是否是质数,因为当枚举到i且成立时,就已经说明i不能被2~i-1整除,说明i已经是质数
  • n最多只有一个大于sqrt(n)的数,因为如果有两个大于,则两数相乘大于n不符合逻辑,所以枚举只需要枚举到i<=n/i,最后剩余的一个不是1就是大于sqrt(n)的最后一个质因子
  • 时间复杂度从O(n)降低到了介于O(logn)~O(sqrt(n))
void divide(int n)
{for(int i = 2; i <= n / i; i ++ )if(n % i == 0){int s = 0; //次数 while(n % i == 0){n /= i;s ++;}cout << i << ' ' << s << endl;}if(n > 1) cout << n << ' ' << 1 << endl;puts(""); //换行 
}

3.筛选质数

  • 埃氏筛法
  • 从小到大枚举质数(不用枚举所有数),每次删除质数的倍数
  • 时间复杂度从O(nlogn)降低为O(nloglogn)
const int N = 1000010;int primes[N], cnt;
bool st[N]; //判断是否是合数void get_primes(int n)
{for(int i = 2; i <= n; i ++ ){if(!st[i]){primes[cnt++] = i;for(int j = i + i; j <= n; j += i) st[j] = true;}}
}
  • 线性筛法
  • i%pj == 0:由于从小向大枚举,pj一定是i的最小质因子,pj一定是pj * i的最小质因子
  • i%pj != 0:由于从小向大枚举,pj一定小于i的所有质因子,pj也一定是pj * i的最小质因子
  • 所以在i%pj == 0时break即可,后面的都不满足了,但是从开始枚举到此的全都满足pj一定是pj * i的最小质因子
  • 时间复杂度比埃氏更低
const int N = 1000010;int primes[N], cnt;
bool st[N];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 % prime[j] == 0) break;}}
}

二、约数

约数,又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。

1.求约数-试除法

  • 约数成对出现,如果d|n,则n/d必然也整除n,所以我们枚举的时候只需要枚举前一部分即可,也就是d<=r/d这一部分
vector<int> get_divisors(int n)
{vector<int> res; //存n的所有约数for(int i = 1; i <= n / i; i ++ ){res.push_back(i);if(i != n / i) res.push_back(n / i);}sort(res.begin(), res.end());return res;
}

2.约数的个数

  • N = P1a1 * P2a2 * P3a3 * …… * Pkak
  • 约数个数 = (a1+1)*(a2+1)*(a3+1)*……*(ak+1)
  • 运用前面分解质因子-试除法
/*题目:给定 n 个正整数 ai,请你输出这些数的乘积的约数个数,答案对 109+7 取模。*/
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>using namespace std;typedef long long LL;const int N = 110, mod = 1e9 + 7;int main()
{int n;cin >> n;unordered_map<int, int> primes;while (n -- ){int x;cin >> x;//分解质因子-试除法for (int i = 2; i <= x / i; i ++ )while (x % i == 0){x /= i;primes[i] ++ ;}if (x > 1) primes[x] ++ ;}LL res = 1;for (auto p : primes) res = res * (p.second + 1) % mod;cout << res << endl;return 0;
}

3.约数之和

  • N = P1a1 * P2a2 * P3a3 * …… * Pkak
  • 约数之和=(P10+P11+……+P1a1)*……*(Pk0+Pk1+……+Pkak)
  • 运用前面分解质因子-试除法
/*题目:给定 n 个正整数 ai,请你输出这些数的乘积的约数之和,答案对 109+7 取模。*/
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>using namespace std;typedef long long LL;const int N = 110, mod = 1e9 + 7;int main()
{int n;cin >> n;unordered_map<int, int> primes;while (n -- ){int x;cin >> x;//分解质因子-试除法for (int i = 2; i <= x / i; i ++ )while (x % i == 0){x /= i;primes[i] ++ ;}if (x > 1) primes[x] ++ ;}LL res = 1;for (auto p : primes){LL a = p.first, b = p.second;LL t = 1;while (b -- ) t = (t * a + 1) % mod; //求公式的每个括号项的技巧res = res * t % mod;}cout << res << endl;return 0;
}

4.最大公约数-欧几里得算法

  • 核心:辗转相除
  • d|a且d|b可以推得:d|a*x+b*y
  • 由上式可得:(a, b)最大公约数 =(b, a mod b)
int gcd(int a, int b)
{return b ? gcd(b, a % b) : a;
}

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

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

相关文章

vivado RAM HDL Coding Techniques

Vivado synthesis可以解释各种RAM编码风格&#xff0c;并将它们映射到分布式RAM中或块RAM。此操作执行以下操作&#xff1a; •无需手动实例化RAM基元 •节省时间 •保持HDL源代码的可移植性和可扩展性从编码示例下载编码示例文件。 在分布式RAM和专用RAM之间的选择块存储器…

基于SSM的电影购票系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的电影购票系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Spri…

AI趋势(01)人工智能发展史简介

说明&#xff1a;简要解读AI的发展历史 1 AI的早期起源&#xff08;1950 年代-1960 年代&#xff09; 1.1 人工智能的概念提出 人工智能的概念最早可以追溯到上世纪50年代&#xff0c;当时计算机科学家John McCarthy提出了“人工智能”这一概念&#xff0c;并于1956年在美国达…

十大经典排序算法之一--------------堆排序(java详解)

一.堆排序基本介绍&#xff1a; 堆排序是利用堆这种数据结构而设计的一种排序算法&#xff0c;堆排序是一种选择排序&#xff0c;它的最坏&#xff0c;最好&#xff0c;平均时间复杂度均为O(nlogn)&#xff0c;它也是不稳定排序。堆是具有以下性质的完全二叉树&#xff1a;每个…

C语言猜数字小游戏智能版

不仅有对错&#xff0c;还有评分系统&#xff0c;根据回答的次数给予合适的反馈。此代码适合linux和安卓系统&#xff0c;如果windows想用得删除\033[xxm之类的ANSI打印转义字符&#xff0c;换成windows对应的清屏、切换颜色函数 #include<stdio.h> #include <stdlib…

LTE-M与NB-IoT蜂窝物联网

大规模、高速连接的部署需要大量带宽的支持。而蜂窝低功耗广域 (LPWA)技术为传感器和短数据突发交易设备在快速的、以 5G 为中心的技术世界中的不间断运行让路。长期演进机器类型通信 (LTE-M) 和窄带物联网 (NB-IoT)等移动物联网技术提供安全且经济高效的蜂窝 LPWA 功能。它们是…

内存基础知识

内存作用&#xff1a;用来存放数据 int x10&#xff1b; xx1&#xff1b; 这会生成一个可执行文件&#xff08;装入模块&#xff09;然后存入内存地址中 绝对装入&#xff1a;-如果知道程序放到内存中哪个位置&#xff0c;编译程序将产生绝对地址的目标代码 可重定位装入&am…

汽车零部件软件开发中常用滤波算法

滑动窗口滤波器:均值滤波与中值滤波的应用及局限性 滑动窗口滤波是数字信号处理中的基本技术,通过在数据序列上移动一个固定大小的窗口并计算窗口内数据点的统计量(如均值或中值)来平滑信号。本文将探讨滑动窗口均值滤波和中值滤波的基本实现、工作原理及其局限性,并引入…

idea 打不开项目 白屏

使用IDEA打开项目&#xff0c; 不知名原因崩溃了&#xff0c; 直接出现缩略图白屏。 解决过程&#xff1a; 尝试过重启IDEA&#xff0c;重启过电脑&#xff0c;重新引入相同项目&#xff08;使用不同路径&#xff0c;存在缓存记录&#xff0c;依然打不开&#xff09;&#xff…

数据结构——lesson3单链表介绍及实现

目录 1.什么是链表&#xff1f; 2.链表的分类 &#xff08;1&#xff09;无头单向非循环链表&#xff1a; &#xff08;2&#xff09;带头双向循环链表&#xff1a; 3.单链表的实现 &#xff08;1&#xff09;单链表的定义 &#xff08;2&#xff09;动态创建节点 &#…

删除链表的倒数第N个节点

删除链表的倒数第N个节点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 进阶&#xff1a;你能尝试使用一趟扫描实现吗&#xff1f; 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例…

蓝桥杯Java组备赛(二)

题目1 import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);int n sc.nextInt();int max Integer.MIN_VALUE;int min Integer.MAX_VALUE;double sum 0;for(int i0;i<n;i) {int x sc.nextInt()…

13.5. 多尺度目标检测

这里是对那一节代码的通俗注释&#xff0c;希望对各位学习有帮助。 值得注意的是&#xff0c;multibox_prior函数的宽高计算网络上有争议&#xff0c;此处我仍认为作者的写法是正确的&#xff0c;如果读者有想法&#xff0c;可以在评论区留言&#xff0c;我们进行讨论。 import…

文件上传漏洞--Upload-labs--Pass03--特殊后缀与::$DATA绕过

方法一&#xff1a;特殊后缀绕过&#xff1a; 一、什么是特殊后缀绕过 源代码中的黑名单禁止一系列后缀名 之外的后缀&#xff0c;称之为‘特殊后缀名’&#xff0c;利用其来绕过黑名单&#xff0c;达到上传含有恶意代码的文件的目的。 二、代码审计 接下来对代码逐条拆解进行…

iocp简单例子

首先说明&#xff1a;纯iocp使用的例子看&#xff1a;纯iocp例子&#xff08;里面的代码可能无法运行&#xff0c;但是下面的代码一定可以运行&#xff0c;可以看看它里面的 PostQueuedCompletionStatus函数的使用&#xff0c;参考参考然后拿出来放到下面的代码里测试&#xff…

VQ23 请按城市对客户进行排序,如果城市为空,则按国家排序(order by和case when的连用)

代码 select * from customers_info order by (case when city is null then country else city end)知识点 order by和case when的连用

VQ30 广告点击的高峰期(order by和limit的连用)

代码 select hour(click_time) as click_hour ,count(hour(click_time)) as click_cnt from user_ad_click_time group by click_hour order by click_cnt desc limit 1知识点 order by和limit的连用&#xff0c;取出所需结果 YEAR() 返回统计的年份 MONTH() 返回统计的月份 D…

解决Ubuntu下网络适配器桥接模式下ping网址不通的情况

问题反应&#xff1a;ping不通网址 打开虚拟机中的设置&#xff0c;更改网络适配器为NAT模式 确定保存更改之后&#xff0c;退出输入如下命令。 命令1&#xff1a; sudo /etc/network/inferfaces 命令2&#xff1a; sudo /etc/init.d/network/ restart

《生产调度优化》专栏导读

文章分类 生产调度优化问题入门相关问题求解调度问题求解效率探讨相关论文解读 生产调度优化问题入门 文章包含重点简述生产车间调度优化问题两种常用的FJSP模型解析FJSP问题的标准测试数据集的Python代码解析FJSP标准测试数据代码 相关问题求解 文章求解器问题类型【作业车…

使用 C++23 从零实现 RISC-V 模拟器(5):CSR

&#x1f449;&#x1f3fb; 文章汇总「从零实现模拟器、操作系统、数据库、编译器…」&#xff1a;https://okaitserrj.feishu.cn/docx/R4tCdkEbsoFGnuxbho4cgW2Yntc RISC-V为每个hart定义了一个独立的控制状态寄存器&#xff08;CSR&#xff09;地址空间&#xff0c;提供了4…