质数

在>1的整数中,如果只包含1和本身这两个约数,就被称为质数(素数)

866 试除法判定

866. 试除法判定质数 - AcWing题库

\(O(n)\)

bool isprime(int x) {
if (x < 2) return false;
for (int i = 2; i < x; i++)
if (x % i == 0) return false;
return true;
}

约数 d 与 n / d 成对出现,可以枚举较小的那一个 \(O(\sqrt{n})\)

\(d <= n/d \\ d^2 <= n \\ d <= \sqrt{n}\)

难点

  • 循环判断条件不要用 sqrt,每次循环都会执行一遍sqrt函数,比较慢
  • 循环判断条件不要用 i * i,存在溢出风险(变成负数)
  • 一定不会溢出的写法是 i <= n / i
#include <iostream>

using namespace std;

bool isprime(int n) {
if (n < 2) return false;
for (int i = 2; i <= n / i; i++)
if (n % i == 0) return false;
return true;
} int main() {
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
if (isprime(x))
cout << "Yes" << endl;
else
cout << "No" << endl;
}
}

867分解质因数

867. 分解质因数 - AcWing题库

质因数指能整除给定正整数的质数。把一个合数分解成若干个质因数的乘积的形式,即求质因数的过程叫做分解质因数。

相关理论证明可看 数论——质数:分解质因数 - 知乎 (zhihu.com)

从2到\(\sqrt{n}\)枚举n的所有质因数,求其指数并输出。还要考虑最多有一个质因素大于\(\sqrt{n}\)的情况,单独判断输出。 最坏 \(O(\sqrt{n})\),最好 \(O(logn)\) (考虑\(2^k\)情况)

#include <iostream>

using namespace std;

void divide(int n) {
for (int i = 2; i <= n / i; i++) {
if (n % i == 0) {
int cnt = 0;
while (n % i == 0) {
cnt++;
n /= i;
}
cout << i << " " << cnt << endl;
}
}
if (n > 1) cout << n << " " << 1 << endl;
} int main() {
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
divide(x);
cout << endl;
}
}

868筛质数

868. 筛质数 - AcWing题库

朴素算法是从前往后删倍数(2~p-1都不是n的约数,所以n是质数)

调和级数\(1/2+1/3+1/4+1/5+...+1/∞\) 极限等于 \(lnn+C\)。

\(lnn < log_2n\),因此朴素算法复杂度为 \(O(nlogn)\)

埃式筛法:只删除2~p-1中质数的倍数,原理跟867类似(算数基本定理:每个正整数都可以唯一表示成素数的乘积)

粗略估计:1~n当中,有\(n/lnn\)个质数,时间复杂度变为 \(O(n)\),真实复杂度 \(O(nloglogn)\),两者差不多一个级别

#include <algorithm>
#include <iostream> using namespace std; const int N = 1e6 + 10;
int primes[N], cnt;
bool st[N]; void get_primes(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) {
primes[cnt++] = n;
for (int j = i + i; j <= n; j += i) st[j] = true;
}
}
} int main() {
int n;
cin >> n;
get_primes(n);
cout << cnt << endl; return 0;
}

线性筛法,\(O(n)\),基本思路一样(基于每个质数的倍数为非质数),当 n 很大时,速度比埃式筛法快一倍。

每个数只会被其最小质因子筛掉

  • i % pj == 0,pj 一定是 i 的最小质因子,pj 一定是 pj * i 的最小质因子
  • i % pj != 0,pj 一定小于 i 的所有质因子,pj 一定是 pj * i 的最小质因子
#include <algorithm>
#include <iostream> using namespace std; const int N = 1e6 + 10;
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] * i <= n; j++) {
st[primes[j] * i] = true;
if (i % primes[j] == 0) break; // primes[j] 一定是 i 的最小质因子
}
}
} int main() {
int n;
cin >> n;
get_primes(n);
cout << cnt << endl; return 0;
}

约数

869 试除法求约数

869. 试除法求约数 - AcWing题库

与866优化原理类似 \(O(\sqrt{n})\)

#include <algorithm>
#include <iostream>
#include <vector> using namespace std; vector<int> get_divisors(int n) {
vector<int> res;
for (int i = 1; i <= n / i; i++) {
if (n % i == 0) {
res.push_back(i);
if (i != n / i) res.push_back(n / i); // 避免平方
}
}
sort(res.begin(), res.end());
return res;
} int main() {
int n;
cin >> n;
while (n--) {
int x;
cin >> x;
auto res = get_divisors(x);
for (auto t : res) cout << t << ' ';
cout << endl;
}
}

870约数个数

利用算术基本定理,每个质因数有(1+n)种选择。m个选择组合得出m个约数

具体原理可看 第四章 数学知识(一)——质数与约数 - 知乎 (zhihu.com)

INT_MAX 约数个数约1500

870. 约数个数 - AcWing题库

求 n 个数的乘积的约数个数,可以求每个数的每个质因子指数之和,然后套用公式。

#include <algorithm>
#include <iostream>
#include <unordered_map> using namespace std; typedef long long LL;
const int 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 prime : primes) res = res * (prime.second + 1) % mod;
cout << res << endl;
return 0;
}

871约数之和

AcWing 871. 约数之和 - AcWing

#include <algorithm>
#include <iostream>
#include <unordered_map> using namespace std; typedef long long LL;
const int 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 prime : primes) {
int p = prime.first, a = prime.second;
LL t = 1;
while (a--) {
t = (t * p + 1) % mod;
}
res = res * t % mod;
}
cout << res << endl;
return 0;
}

872最大公约数

872. 最大公约数 - AcWing题库

欧几里得算法(辗转相除法)

#include <algorithm>
#include <iostream>
#include <unordered_map> using namespace std; // a 和 0 的最大公约数是 a
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; } int main() {
int n;
cin >> n;
while (n--) {
int a, b;
cin >> a >> b;
cout << gcd(a, b) << endl;
}
return 0;
}

C++算法之旅、08 基础篇 | 质数、约数的更多相关文章

  1. iOS系列 基础篇 08 文本与键盘

    iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...

  2. 【算法与数据结构】在n个数中取第k大的数(基础篇)

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍            在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...

  3. ESP8266开发之旅 基础篇① 走进ESP8266的世界

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  4. ESP8266开发之旅 基础篇② 如何安装ESP8266的Arduino开发环境

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  5. ESP8266开发之旅 基础篇③ ESP8266与Arduino的开发说明

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  6. ESP8266开发之旅 基础篇④ ESP8266与EEPROM

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  7. ESP8266开发之旅 基础篇⑥ Ticker——ESP8266定时库

    授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...

  8. Java多线程系列--“基础篇”08之 join()

    概要 本章,会对Thread中join()方法进行介绍.涉及到的内容包括:1. join()介绍2. join()源码分析(基于JDK1.7.0_40)3. join()示例 转载请注明出处:http ...

  9. 【SSM之旅】Spring+SpringMVC+MyBatis+Bootstrap整合基础篇(一)项目简介及技术选型相关介绍

    试水 一直想去搭建个自己的个人博客,苦于自己的技术有限,然后也个人也比较懒散.想动而不能动,想动而懒得动,就这么一直拖到了现在.总觉得应该把这几年来的所学总结一番,这样才能有所成长. 不知在何时,那就 ...

  10. 《量化投资:以MATLAB为工具》连载(1)基础篇-N分钟学会MATLAB(上)

    http://blog.sina.com.cn/s/blog_4cf8aad30102uylf.html <量化投资:以MATLAB为工具>连载(1)基础篇-N分钟学会MATLAB(上) ...

随机推荐

  1. PostgreSQL 12 文档: 系统表

    第 51 章 系统目录 目录 51.1. 概述 51.2. pg_aggregate 51.3. pg_am 51.4. pg_amop 51.5. pg_amproc 51.6. pg_attrde ...

  2. 1、笔记本刷ubuntu,安装饥荒服务器

    目录 笔记本刷ubuntu,安装饥荒服务器 一.准备 二.笔记本刷机 1.制作Ubuntu server U盘启动盘 2.刷机 3.设置电源不休眠 三.安装饥荒服务器 四.最后说下网络 笔记本刷ubu ...

  3. IIS部署的应用无法自动注册到Nacos

    问题描述: 自己开发的某系统后台API接入nacos,在IIS上部署无法自动注册到nacos服务列表中.其根本原因是网站处于休眠状态,当某请求访问该网站时,网站被激活,nacos注册成功. 但这块有个 ...

  4. PNG结构

    参考此博客 PNG的文件头总是固定的八个字节 89 50 4E 47 0D 0A 1A 0A 数据块长度13 00 00 00 0D 文件头数据块标识IDCH 49 48 44 52 13位数据块(I ...

  5. 从逻辑门到 CPU

    目的,造一个很简单的,概念上的 CPU,虽然简单,但是是五脏俱全的 CPU 从最基础的逻辑门开始造,零基础可以看 制造基本武器:与门.非门.或门 现在计算机都是二进制,那二进制是一开始就能想到的吗?显 ...

  6. Python数据分析易错知识点归纳(四):Matplotlib

    四.matplotlib 基本特性 import matplotlib.pyplot as plt import numpy as np x = np.linspace(-3, 3, 50) y1 = ...

  7. PerfView专题 (第十五篇): 如何洞察 C# 中的慢速方法

    一:背景 1. 讲故事 在 dump 分析旅程中,经常会遇到很多朋友反馈一类问题,比如: 方法平时都执行的特别快,但有时候会特别慢,怎么排查? 我的方法第一次执行特别慢,能看到慢在哪里吗? 相信有朋友 ...

  8. .NET ORM 鉴别器 和 TDengine 使用 -SqlSugar

    SqlSugar ORM SqlSugar 是一款 老牌 .NET 开源多库架构ORM框架 ,一套代码能支持多种数据库像像Admin.net.Blog.Core.CoreShop等知名开源项目都采用了 ...

  9. Promise的理解与使用(一)

    一.Promise是什么?Promise是JS中进行异步操作的新的解决方案(旧的方案是回调函数的形式,回调函数里嵌套函数)从语法上来说,Promise是一个构造函数.从功能上来说,用Promise的实 ...

  10. 【go笔记】使用标准库flag解析命令行参数

    前言 Go语言标准库中提供了一个包flag可以解析命令行参数. 示例代码:文件读取 package main import ( "fmt" "flag" &qu ...