数学知识1.2-约数
一、简述
本文章主要介绍有关约数的基础算法。
二、约数
约数,又称因数。整数
三、试除法求约数
设一个数
参考试除法判断质数,如果对于一个数
模板题AcWing869.试除法求约数
题目描述
给定
输入格式
第一行包含整数
接下来
输出格式
共
数据范围
1≤
输入样例
2
6
8
输出样例
1 2 3 6
1 2 4 8
解题思路
试除法,并且对于平方数此类的数,我们要对它的约数进行去重,这里我们可以采用 set,同时 set 也可以实现自动排序,无需我们再对存放约数的数组进行排序。
C++代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
set<int> get_divisors(int x)
{
set<int> res;
for(int i = 1; i <= x / i; i ++)
{
if(x % i == 0)
{
res.insert(i);
res.insert(x / i);
}
}
return res;
}
int main()
{
int n;
cin >> n;
for(int i = 1; i <= n; i ++)
{
int x;
cin >> x;
set<int> t = get_divisors(x);
for(auto v : t)
cout << v << ' ';
cout << endl;
}
return 0;
}
四、约数个数
- 算术基本定理:任何一个大于1的自然数 N,都可以唯一分解成有限个质数的乘积。
N = ⋅⋅⋅ ,这里 < < ⋅⋅⋅ < 且均为质数,其指数均是正整数。 - 约数个数 = (
+ 1) * ( + 1) * ... * ( + 1)。
模板题AcWing870. 约数个数
题目描述
给定
输入格式
第一行包含整数
接下来
输出格式
输出一个整数,表示所给正整数的乘积的约数个数,答案需对 109+7 取模。
数据范围
1≤
输入样例
3
2
6
8
输出样例
12
解题思路
试除法,因为我们要利用对应质因数的指数,我们使用哈希表存储。
C++代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 110, MOD = 1e9 + 7;
typedef long long LL;
int n;
unordered_map<int, int> primes;
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
int x;
cin >> x;
for(int j = 2; j <= x / j; j ++)
{
while(x % j == 0)
{
x /= j;
primes[j] ++;
}
}
if(x > 1) primes[x] ++;
}
LL res = 1;
for(auto [k, v] : primes)
{
res = (res * (v + 1)) % MOD;
}
cout << res;
return 0;
}
五、约数之和
约数之和的依据也是算术基本定理。
约数之和 = (
模板题AcWing871.约数之和
题目描述
给定
输入格式
共一行,包含整数
接下来
输出格式
输出一个整数,表示所给正整数的乘积的约数之和,答案需对 109+7 取模。
数据范围
1≤
输入样例
3
2
6
8
输出样例
252
解题思路
参考前面试除法计算约数个数,我们利用哈希表存储质因数及其指数之后,对质因数
C++代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 110, MOD = 1e9 + 7;
typedef long long LL;
int n;
unordered_map<int, int> primes;
int main()
{
cin >> n;
for(int i = 1; i <= n; i ++)
{
int x;
cin >> x;
for(int j = 2; j <= x / j; j ++)
{
while(x % j == 0)
{
x /= j;
primes[j] ++;
}
}
if(x > 1) primes[x] ++;
}
LL res = 1;
for(auto [k, v] : primes)
{
LL t = 1;
int p = k, a = v;
while(a --)
{
t = (t * p + 1) % MOD;
}
res = (res * t) % MOD;
}
cout << res;
return 0;
}
六、最大公约数
计算两个数的最大公约数我们常使用的算法是辗转相除法(欧几里得算法)。
核心思想:如果
欧几里得算法的表示:(
证明:首先
- 左->右:
| , | ,则 | , | ,等号成立。 - 右->左:
| , | ,则 | 也就是 | 且 | ,等号成立。
证毕。
模板题AcWing872.最大公约数
题目描述
给定
输入格式
共一行,包含整数
接下来
输出格式
输出共
数据范围
1≤
1≤
输入样例
2
3 6
4 6
输出样例
3
2
解题思路
辗转相除法。
C++代码
#include <iostream>
using namespace std;
int gcd(int a, int b)
{
if(a % b == 0) return b;
return gcd(b, a % b);
}
int n;
int main()
{
cin >> n;
while(n --)
{
int a, b;
cin >> a >> b;
printf("%d\n", gcd(a, b));
}
return 0;
}
本文来自博客园,作者:Cocoicobird,转载请注明原文链接:https://www.cnblogs.com/Cocoicobird/p/16695044.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】