约数——数论算法

数论基础知识

本篇文章主要讲述数论中基础算法 约数部分的内容
提示:本篇文章代码参考ACWing

文章目录

  • 数论基础知识
  • 一、约数是什么?
  • 二、约数的相关算法
    • 1.枚举出某一个数的所有约数
    • 2.求约数的个数
    • 3.最大公约数
    • 4.约数之和


!!:以下是本篇文章正文内容,下面案例可供参考

一、约数是什么?

约数,又叫因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数,我们就说a能被b整除,或b能整除a。a称为b的倍数,b称为a的约数。

二、约数的相关算法

1.枚举出某一个数的所有约数

试除法:
d|n => n/d|n 枚举范围为1~n/d
时间复杂度:O(sqrt(n))

代码如下():

vector <int> get_divisors(int n)
{
	vector<int> res;
	for(int i=1;i<=n;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;
 } 

2.求约数的个数

由算数基本定理:\num(n) = p1^a1 * p2^a2*…pn*an.(p1,p2…为质数)
可知约数的个数由a1,a2…an的取法确定,每一个质数的指数的取法有(a+1)种取法,故
约数个数n=(a1+1)(a2+1)(a3+1)(a4+1)…(an+1)
代码如下(示例):

typedef long long ll;
const int mod=le9+7;
int main()
{
	unodered_map <int,int> primes;
	int n;
	cin>>n;
	
	while(n--){
		cin>>a;
		
		for(int i=1;i<n/i;i++){
			while(a%i==0){
				a=a/i;
				primes[i]]++;
			}
			if(a>1) primes[a]++;
		}
	}
	ll res = 1;
	for(auto prime : primes) res = res * (prime.second +1)%mod;
	
	cout<<res<<endl;
	
	return 0;
}

3.最大公约数

欧几里得算法/辗转相除法
核心原理: d|n,d|m,则d|(n+m) 和d|xn+ym
即(a,b) = (b,a mod b)

三元运算符’ ? :'的用法 true执行:前的表达式,false执行后面的表达式

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

int main()
{
 	int n;
 	cin>>n;
 	while(n--){
 		int a,b;
 		cin>>a>>b;
 		cout<<gcd(a,b)<<endl;
 	}
 	
	return 0;
}
 } 

4.约数之和

同样由算数基本定理:
\num(n) = p1^a1 * p2^a2 *… * .pn^an.(p1,p2…为质数)
参考求约数个数的算法,乘法分配得到:

typedef long long ll;
const int mod=le9+7;
int main()
{
	unodered_map <int,int> primes;
	int n;
	cin>>n;
	
	while(n--){
		cin>>a;
		
		for(int i=1;i<n/i;i++){
			while(a%i==0){
				a=a/i;
				primes[i]]++;
			}
			if(a>1) primes[a]++;
		}
	}
	ll res = 1;
	for()
	{
		int p=primes.first;
		int a=primes.second;
		ll t=1;//总和 
		while(a--)
			t=(t*p+1) % mod; 
		 
		res = res*t % mod;
	 } 
	 
	cout<<res<<endl;
	
	return 0;
}


以上内容仅为提供思路,如有错误 欢迎指正!

你可能感兴趣的:(数论算法,c++)