约数

约数

什么是约数

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

约数的相关运算

求一个数的所有约数

用试除法枚举,时间复杂度\(O(\sqrt n)\)

void Divisor(int n){
	int t;
	for(int i = 1; i <= sqrt(n); i++){
		if(n % i == 0) cout << i << " ";
	}
	int res = sqrt(n);
	if(res * res == n)  t = res - 1;
	else t = res;
	for(int i = t; i >= 1; i--){
		if(n % i == 0) cout << n/i << " ";
	}
} 

如何求约数个数

我们都知道,每一个合数都可以写成几个素数相乘的形式,其中每个素数都是这个合数的因数。所以我们就可以把\(n\)分解成:\(n=p_1^{a_1}\times p_2^{a_2}\times \dots \times p_k^{a_k}\),其中\(p_1,p_2,\dots,p_k\)是不同的素数,\(a_1,a_2,\dots,a_k\)是正整数。

由约数定义可知\(p_1^{a_1}\)的约数有:\(p_1^0, p_1^1, p_1^2,....p_1^{a_1}\),共\((a_1+1)\)个;同理\(p_2^{a_2}\)的约数有\((a_2+1)\)个,\(\dots\)\(p_k^{a_k}\)的约数有\((a_k+1)\)个。

故根据乘法原理:\(n\)的正约数的个数为\(\prod_{i = 0}^n(a_i+1)=(a_1+1)\times(a_2+1)\times\dots\times(a_n+1)\)

void NumDivisor(int n){
	map<int,int>ma;
	map<int,int>::iterator iter;
	ll res = 1;
	for(int i = 2; i <= n / i; i++){
		while(n % i == 0){
			n /= i;
			ma[i]++;
		}
	}
	if(n > 1) ma[n]++;
	for(iter = ma.begin(); iter != ma.end(); iter++){
		res = res * (iter->second + 1);
	} 
	cout << res;
} 

最大公约数

轻点一下有惊喜

如何求约数和

由约数定义我们可知\(p_1^{a_1}\)的约数有:\(p_1^0, p_1^1, p_1^2,....p_1^{a_1}\),共\((a_1+1)\)个;同理\(p_2^{a_2}\)的约数有\((a_2+1)\)个,\(\dots\)\(p_k^{a_k}\)的约数有\((a_k+1)\)个。而实际上\(n\)的约数是在\(p_1^{a_1},p_2^{a_2},\dots,p_k^{a_k}\)每个约数中分别挑选一个相乘得来,这样可知共有\((a_1+1)\times(a_2+1)\times\dots\times(a_k+1)\)种挑法,即约数的个数,有乘法原则我们可知它们的和为:\(f(n)=(p_1^0+p_1^1+p_1^2+…p_1^{a_1})\times(p_2^0+p_2^1+p_2^2+…p_2^{a_2})…(p_k^0+p_k^1+p_k^2+…p_k^{a_k})\)

ll fastpow(int a, int n){
	ll res = 1;
	while(n){
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

void SumDivisor(int n){
	ll res = 0, ans = 1;
	map<int,int>ma;
	map<int,int>::iterator iter;
	for(int i = 2;  i <= n / i; i++){
		while(n % i == 0){
			n /= i;
			ma[i]++;
		}
	}
	if(n > 1) ma[n]++; 
	for(iter = ma.begin(); iter != ma.end(); iter++){
		res = 0;
		for(int i = 0; i <= iter->second; i++){
			res = (res + fastpow(iter->first,i));
		}
		ans = ans * res;
	} 
	cout << ans;
} 
posted @ 2021-05-18 20:44  h星宇  阅读(281)  评论(0编辑  收藏  举报