求约数,约数个数,约数之和,最大公约数
创始人
2024-05-11 17:53:53
0次

求约数

求一个数的所有约数,枚举 [1,n][1,\sqrt n][1,n​] 的所有整数,能整除 n 的就是约数,另一半约数就是 n / i.

vector get_divisors(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);}}return res;
}

约数个数

求约数个数基于约数个数定理:

对于一个大于 111 的正整数 nnn 可以分解质因数:
n=∏i=1kpiai=p1a1⋅p2a2⋅⋯⋅pkakn=\prod_{i=1}^kp_i^{a_i}=p_1^{a_1}\cdot p_2^{a_2}\cdot\cdots\cdot p_k^{a_k} n=i=1∏k​piai​​=p1a1​​⋅p2a2​​⋅⋯⋅pkak​​
则 nnn 的正约数的个数是
d(n)=∏i=1k(ai+1)=(a1+1)(a2+1)⋯(ak+1)d(n)=\prod_{i=1}^k(a_i+1)=(a_1+1)(a_2+1)\cdots(a_k+1) d(n)=i=1∏k​(ai​+1)=(a1​+1)(a2​+1)⋯(ak​+1)
证明:

p1a1p_1^{a_1}p1a1​​ 的约数有 p10,p11,p12,⋯,p1a1p_1^0,p_1^1,p_1^2,\cdots,p_1^{a_1}p10​,p11​,p12​,⋯,p1a1​​ 共 a1+1a_1+1a1​+1 个,同理 pkakp_k^{a_k}pkak​​ 的约数有 ak+1a_k+1ak​+1 个。

由乘法原理,nnn 的约数个数就是 (a1+1)(a2+1)⋯(ak+1)(a_1+1)(a_2+1)\cdots(a_k+1)(a1​+1)(a2​+1)⋯(ak​+1)

代码:

其实和质因数分解很相似,只要会质因数分解,就会求因数个数

int num_divisors(int n) {int res = 1;for (int i = 2; i <= n / i; ++i) {if (n % i == 0) {int s = 0;while (n % i == 0) {n /= i;++s;}res *= s + 1;}}if (n > 1) res *= 2;return res;
}

约数之和

对于一个大于 111 的正整数 nnn 可以分解质因数:
n=∏i=1kpiai=p1a1⋅p2a2⋅⋯⋅pkakn=\prod_{i=1}^kp_i^{a_i}=p_1^{a_1}\cdot p_2^{a_2}\cdot\cdots\cdot p_k^{a_k} n=i=1∏k​piai​​=p1a1​​⋅p2a2​​⋅⋯⋅pkak​​
n 的约数之和是
σ(n)=(p10+p11+p12+⋯+p1a1)(p20+p21+p22+⋯+p2a2)⋯(pk0+pk1+pk2+⋯+pkak)\sigma(n)=(p_1^0+p_1^1+p_1^2+\cdots+p_1^{a_1})(p_2^0+p_2^1+p_2^2+\cdots+p_2^{a_2})\cdots(p_k^0+p_k^1+p_k^2+\cdots+p_k^{a_k}) σ(n)=(p10​+p11​+p12​+⋯+p1a1​​)(p20​+p21​+p22​+⋯+p2a2​​)⋯(pk0​+pk1​+pk2​+⋯+pkak​​)
等比数列求和,上式可以写成
σ(n)=p1a1+1−1p1−1×p2a2+1−1p2−1×⋯×pkak+1−1pk−1\sigma(n)=\frac{p_1^{a_1+1}-1}{p_1-1}\times\frac{p_2^{a_2+1}-1}{p_2-1}\times\cdots\times\frac{p_k^{a_k+1}-1}{p_k-1} σ(n)=p1​−1p1a1​+1​−1​×p2​−1p2a2​+1​−1​×⋯×pk​−1pkak​+1​−1​
代码:

int sum_divisors(int n) {int res = 1;for (int i = 2; i <= n / i; ++i) {if (n % i == 0) {int s = i;while (n % i == 0) {n /= i;s *= i;}res *= (s - 1) / (i - 1);}}if (n > 1) res *= (n * n - 1) / (n - 1);return res;
}

最大公约数

欧几里得算法

欧几里得算法又称辗转相除法,计算公式为 gcd⁡(a,b)=gcd⁡(b,amodb)\gcd(a,b)=\gcd(b,a\mod b)gcd(a,b)=gcd(b,amodb)

假如需要求 199719971997 和 615615615 两个正整数的最大公约数,用欧几里得算法,是这样进行的:

1997÷615=3(余152)1997 ÷ 615 = 3 (余 152)1997÷615=3(余152)

615÷152=4(余7)615 ÷ 152 = 4(余7)615÷152=4(余7)

152÷7=21(余5)152 ÷ 7 = 21(余5)152÷7=21(余5)

7÷5=1(余2)7 ÷ 5 = 1 (余2)7÷5=1(余2)

5÷2=2(余1)5 ÷ 2 = 2 (余1)5÷2=2(余1)

2÷1=2(余0)2 ÷ 1 = 2 (余0)2÷1=2(余0)

至此,最大公约数为 111

以除数和余数反复做除法运算,当余数为 000 时,取当前算式除数为最大公约数,所以就得出了 199719971997 和 615615615 的最大公约数 111。

代码:

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

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...