约数
约数个数
算数基本定理
定义: 一个合数可以分解为质因数的乘积的形式,如果无论顺序的话,此分解唯一。
约数个数定理
定义:
任何一个 ≥2的自然数 N都可以唯一分解成有限个素数(质数)的幂的乘积。
N = P1a1 * P2a2 * P3a3 * ……* Pmam。
它的约数个数为 (a1+1)(a2+1)(a3+1)…(am+1);
代码实现
#include <iostream>
using namespace std;
int n, primes[10010], primes_num[10010], cnt=0;
int main()
{
//输入一个n,求n的所有约数个数
cin >> n;
for(int i = 2; i <= n/i; i ++){
cnt ++;
while(n % i == 0){
n /= i;
primes[cnt] = i; //存质因数
primes_num[cnt] ++; //质因数个数
}
}
if(n > 1) primes[++cnt] = n, primes_num[cnt] ++;
for(int i = 1; i <= cnt; i ++){
cout << "质因数 = " << primes[i] << " 指数 = " << primes_num[i] << endl;
}
int ans = 1;
for(int i = 1; i <= cnt; i ++){
ans *= primes_num[i] + 1;
}
cout << "质因数总数为:" << ans;
return 0;
}
约数之和
约数和定理
定义:
对于一个大于1的正整数n可以分解质因数:N = P1a1 * P2a2 * P3a3 * ……* Pmam。
它的约数个数为 d(n) = (a1+1)(a2+1)(a3+1)…(am+1);
所以它的 d(n) 个正约数的和为 :(n) = ( P10+P11+…+P1a1)( P20+P21+…+P2a2)…( Pm0+Pm1+…+Pmam)。
快速幂
最大公约数
1.辗转相除法(欧几里得算法)
定义:
两个数的最大公约数是可以同时整除这两个数的最大正整数。
基本流程
设两个数为a、b(a≥b),求a和b最大公约数(Greatest common divisor)gcd(a,b)的步骤如下:
a除以b,得a÷b=q........r1(r1≥0),r1为第一次的余数;
若r1=0,则gcd(a,b)=b;
若r1≠0,再用b除以r1,得余数r2;
如此反复,直到某余数等于0,则该余数就是我们所找的最大公约数gcd(a,b)。
代码实现
递归版
//辗转相除法(欧几里得算法)
//递归版
#include<iostream>
using namespace std;
int gcd(int a , int b)
{
// return b == 0 ? a : gcd(b , a%b);
if(b != 0)
{
return gcd(b , a%b);
}
else return a;
}
int main()
{
int a , b;
cin >> a >> b;
// if(a < b) swap(a , b);
int ans = gcd(a , b);
// int ans = gcd1(a , b);
cout << ans;
return 0;
}
非递归版
//辗转相除法(欧几里得算法)
//递归版
#include<iostream>
using namespace std;
非递归版
int gcd1(int a , int b)
{
if(a < b) swap(a , b);
while(b != 0)
{
int temp = a;
a = b;
b = temp%b;
}
return 0;
}
int main()
{
int a , b;
cin >> a >> b;
// if(a < b) swap(a , b);
// int ans = gcd(a , b);
int ans = gcd1(a , b);
cout << ans;
return 0;
}
2.更相减损术
基本流程
两个数的最大公约数等于它们中 较小的数 和 两数之差 的最大公约数。
60和45的最大公约数是15(60 = 4 × 15;45 = 3 × 15);
60 − 45 = 15,所以15和45的最大公约数也是15;
45 − 15 = 30,所以30和15的最大公约数也是15;
30 − 15 = 15,所以15和15的最大公约数也是15;
15 − 15 =0,最后剩下15和0,所以60和45的最大公约数是15。
int gcd(int a,int b)
{
while(a != b)
{
if(a>b)
{
a = a - b;
}
else
{
b = b - a;
}
}
return a;
}
最小公倍数
定义:两个数的最小公倍数等于两个数的乘积除以最大公约数。
设两个数a,b。m为a,b的最大公约数,设a,b的最小公倍数为n,则 n = a * b / m;
代码
#include<iostream>
int gcd(int a,int b)
{
while(a != b)
{
if(a>b)
{
a = a - b;
}
else
{
b = b - a;
}
}
return a;
}
int main()
{
int a , b;
cin >> a >> b;
// if(a < b) swap(a , b);
// int ans = gcd(a , b);
int m = gcd1(a , b);
int n = a * b / m;
cout << "最大公约数:" << m << "最小公倍数:" << n << endl;
return 0;
}
引用:部分内容参考了一些大佬。