数据结构与算法学习笔记----约数

数据结构与算法学习笔记----约数

@@ author: 明月清了个风

@@ first publish time: 2024.12.30

ps⭐️主要是求约数,约数的个数,约数的和,涉及到算术基本定理的相关内容,第三题的讲解合并在第二题的思路里一起了。

Acwing 869. 试除法求约数

原题链接\]([869. 试除法求约数 - AcWing题库](https://www.acwing.com/problem/content/description/871/)) 给定 n n n个正整数 a i a_i ai,对于每个整数 a i a_i ai,请你按照从小到大的顺序输出它的所有约数 #### 输入格式 第一行包含整数 n n n, 接下来 n n n行,每行包含一个正整数 a i a_i ai。 #### 输出格式 输出 n n n行,其中每 i i i行输出第 i i i个整数 a i a_i ai的所有约数。 #### 数据范围 1 ≤ n ≤ 100 1 \\le n \\le 100 1≤n≤100, 1 ≤ a i ≤ 2 × 1 0 9 1 \\le a_i \\le 2\\times 10\^9 1≤ai≤2×109 #### 思路 试除法和质数中是一样的,只是我们统计的量不一样了 需要注意的就是时间复杂度了,**数论中的题目需要注意时间复杂度**,这关系到我们要使用什么方法解决 这题的时间复杂度是 O ( n × a ) O(n \\times \\sqrt{a}) O(n×a ), a a a的范围如题,因此可以得到整体时间复杂度大概在400万\~500万。 #### 代码 ```cpp #include #include #include #include using namespace std; vector get_dividers(int n) { vector 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; vector ans = get_dividers(x); for(auto t : ans) cout << t << ' '; cout << endl; } return 0; } ``` ### Acwing 870. 约数个数 \[原题链接\]([870. 约数个数 - AcWing题库](https://www.acwing.com/problem/content/872/)) 给定 n n n个正整数 a i a_i ai,请你输出这些数的乘积的约数个数,答案对 1 0 9 + 7 10\^9 + 7 109+7取模。 #### 输入格式 第一行包含整数 n n n, 接下来 n n n行,每行包含一个正整数 a i a_i ai。 #### 输出格式 输出一个整数,表示所给正整数的乘积的约数个数,答案需对 1 0 9 + 7 10\^9 + 7 109+7取模。 #### 数据范围 1 ≤ n ≤ 100 1 \\le n \\le 100 1≤n≤100, 2 ≤ a i ≤ 2 × 1 0 9 2 \\le a_i \\le 2 \\times 10\^9 2≤ai≤2×109 #### 思路 这里就要用到算术基本定理(这个定理的相关内容从下面的红字开始,若想跳过直接往下看蓝字)了。 算术基本定理,又称为**正整数的唯一分解定理**,是初等数论中一个非常重要的定理。它揭示了整数的基本性质,具体表述为: **任何一个大于1的自然数,如果不为质数,那么它可以唯一分解成有限个质数的乘积。** 数学上,这可以表达为: N = p 1 a 1 × p 2 a 2 × p 3 a 3 × ⋯ × p n a n N = p_1\^{a_1} \\times p_2\^{a_2} \\times p_3\^{a_3} \\times \\cdots \\times p_n\^{a_n} N=p1a1×p2a2×p3a3×⋯×pnan 其中, p 1 \< p 2 \< p 3 \< ⋯ \< p n p_1 \< p_2 \< p_3 \< \\cdots \< p_n p1\ #include #include #include #include using namespace std; typedef long long LL; const int mod = 1e9 + 7; int main() { int n; cin >> n; unordered_map 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; } ``` ### Acwing 871. 约数之和 \[原题链接\]([871. 约数之和 - AcWing题库](https://www.acwing.com/problem/content/873/)) 给定 n n n个正整数 a i a_i ai,请你输出这些数的乘积的约数之和,答案对 1 0 9 + 7 10\^9 + 7 109+7取模。 #### 输入格式 第一行包含整数 n n n, 接下来 n n n行,每行包含一个正整数 a i a_i ai。 #### 输出格式 输出一个整数,表示所给正整数的乘积的约数之和,答案需对 1 0 9 + 7 10\^9 + 7 109+7取模。 #### 数据范围 1 ≤ n ≤ 100 1 \\le n \\le 100 1≤n≤100, 2 ≤ a i ≤ 2 × 1 0 9 2 \\le a_i \\le 2 \\times 10\^9 2≤ai≤2×109 #### 代码 ```cpp #include #include #include #include #include using namespace std; typedef long long LL; const int mod = 1e9 + 7; int main() { int n; cin >> n; unordered_map 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 a = prime.first, b = prime.second; LL t = 1; while(b --) t = (t * a + 1) % mod; res = res * t % mod; } cout << res << endl; return 0; } ```

相关推荐
少年、潜行1 天前
F1C100/200S学习笔记(2)-- 初次FLASH启动(裸机)和SD卡启动(Linux)
linux·笔记·f1c200s
雍凉明月夜1 天前
深度学习网络笔记Ⅰ(CNN)
网络·笔记·深度学习·神经网络·学习·cnn
wljun7391 天前
六、OrcaSlicer 切片之区域
算法·切片软件 orcaslicer
todoitbo1 天前
告别复杂笔记软件!Memos+cpolar,让你的笔记随时随地可用
网络·笔记·内网穿透·cpolar·软件·memos
2401_841495641 天前
【LeetCode刷题】跳跃游戏Ⅱ
数据结构·python·算法·leetcode·数组·贪心策略·跳跃游戏
leaves falling1 天前
动态规划讲解
算法·动态规划
钓鱼的肝1 天前
GESP系列(3级)小杨的储蓄
开发语言·数据结构·c++·笔记·算法·gesp
MicroTech20251 天前
MLGO微算法科技推出人工智能与量子计算融合新成果:基于QLSS与LCHS的量子DPM算法技术
人工智能·科技·算法
AndrewHZ1 天前
【图像处理基石】[特殊字符]圣诞特辑:10+经典图像处理算法,让你的图片充满节日氛围感!
图像处理·人工智能·opencv·算法·计算机视觉·stable diffusion·节日氛围感
艾醒1 天前
大模型原理剖析——矩阵吸收优化:LLM推理加速的核心原理与实践
算法