数学知识:约数的详细解析

🎬 博主名称个人主页

🔥 个人专栏 : 《算法通关》《Java讲解》

⛺️心简单,世界就简单

序言

讲一下约数,平时做题时候还是经常会出现的,比如求两个数的最大公约数,求一个数的因数个数
目录

🎠序言

🎠试除法求约数

🎠约数个数

🎃内容讲解

🎃公式总结

🎠约数之和

🎠欧几里得算法


试除法求约数

因为约数也是成对出现的,比如2 * 6 = 12,我们就只用求出来2后然后直接把12 / 2也push_back()里面就行,所以我们的循环条件是到n / i

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

const int N = 1e6 +10; 

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;
	}
}

约数个数

内容讲解

如果我直接拿公式可能看不大懂,所以我就先举个例子

eg.求12的约数个数

第一步: 分解成质数相乘的样子:12 = 2 × 2 × 3 = 2² × 3¹

**第二步:**理解约数是怎么来的L:

  • 对于质数2:有3种选择

    • 选0个2(就是1)

    • 选1个2(就是2)

    • 选2个2(就是4)

  • 对于质数3:有2种选择

    • 选0个3(就是1)

    • 选1个3(就是3)

**第三步:**比喻一下

  • 上衣有3种选择(2⁰, 2¹, 2²)

  • 裤子有2种选择(3⁰, 3¹)

总搭配数 = 3 × 2 = 6 种

总结

这6种搭配就是12的所有约数:

1 = 2⁰ × 3⁰

2 = 2¹ × 3⁰

3 = 2⁰ × 3¹

4 = 2² × 3⁰

6 = 2¹ × 3¹

12 = 2² × 3¹


公式总结

如果一个数分解成:质数1^a × 质数2^b × 质数3^c × ...

那么约数个数 = (a+1) × (b+1) × (c+1) × ...

我们拿个题来看一下

这道题让我求一堆数相乘后的约数,笨方法当然是先相乘之后再求质数个数,但我们实际上可以直接用一个哈希表记录一下每个数的质数然后++就行

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#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;
	
}

约数之和

这个求和其实我感觉很妙

就是我们上面不是得到了约数之和吗,然后我们还拿这个12来看

12 = 2 × 2 × 3 = 2² × 3¹

约数为 1 2 3 4 6 12 ,那么和就是28了

我们还可以发现(1 + 2 + 4) * (1 + 3)= 28

然后我们的结论就是求出质因数的和然后相乘,就是下面这一步

cpp 复制代码
	int p = prime.first, a = prime.second;
		LL t = 1;
		while(a --){
			t = (t * p + 1) % mod;
		
		}
cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#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;
	
}

欧几里得算法

就是求最大公约数,这个大家都会就不详细说明了,就是辗转相除法,当b=0时候,就直接返回a的值就行

cpp 复制代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>

using namespace std;

typedef long long LL;

const int mod = 1e9 +7; 

int gcd(int a, int b){
	return b ? gcd(b, a % b) : a;
} 

int main(){
	int n;
	 scanf("%d", &n);
	 while(n --){
	 	int a, b;
	 	scanf("%d%d", &a, &b);
	 	printf("%d\n", gcd(a, b));
	 }
}
相关推荐
裕晟资质规划5 小时前
武器装备科研生产单位保密资质申请方法论:条件模型与流程拆解
人工智能·算法
en.en..6 小时前
C语言 标准输入 / 输出缓冲区
算法
吃好睡好便好8 小时前
查找函数的使用
学习·算法·matlab·生活·查找函数
学习星球8 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
靠沿9 小时前
贪心算法专题(二)
算法·贪心算法
猎头南楼10 小时前
具身智能模型部署方向的能力要求与技术栈梳理
人工智能·深度学习·算法
啥都想学点的研究生11 小时前
一篇文章讲清楚:线性回归问题的求解——正规方程法
算法·机器学习·线性回归
青少儿编程课堂11 小时前
树状数组精讲:逆序对计数与离散化(附双语言解法)
算法·树状数组·离散化·信息学奥赛·逆序对
血小板要健康11 小时前
网格 dfs 与 FloodFill:从岛屿、区域到搜索路径
笔记·算法·leetcode·深度优先
VALENIAN瓦伦尼安教学设备12 小时前
设备状态检测振动分析实训台案例分析
大数据·数据库·人工智能·嵌入式硬件·算法