寒假训练营 基础数论 第2节 笔记

约数

约数个数

算数基本定理

定义: 一个合数可以分解为质因数的乘积的形式,如果无论顺序的话,此分解唯一。

约数个数定理

定义
任何一个 ≥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.更相减损术

基本流程

两个数的最大公约数等于它们中 较小的数 和 两数之差 的最大公约数。

6045的最大公约数是1560 = 4 × 1545 = 3 × 15);

6045 = 15,所以1545的最大公约数也是154515 = 30,所以3015的最大公约数也是153015 = 15,所以1515的最大公约数也是151515 =0,最后剩下150,所以6045的最大公约数是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;
}

引用:部分内容参考了一些大佬。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值