求约数,约数个数,约数之和,最大公约数
创始人
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;
}

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...