利用算术基本定理求解约数个数 + 约数之和

Posted on 2022-04-04 18:01  ZheyuHarry  阅读(126)  评论(0编辑  收藏  举报

先前我们已经介绍过了怎么判断质数和约数,现在我们对于约数的个数和约数之和也要进行求解,而求解的方法就是根据算术基本定理来的!

 

先介绍一下什么是算术基本定理:

算术基本定理可表述为:任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积N=P1^a1*P2^a2*P3^a3......Pn^an,这里P1<P2<P3......<Pn均为质数,其中指数ai是正整数。这样的分解称为 的标准分解式

 

那么一直这个之后我们是不是可以知道这个自然数N的约数也是这样的形式D=P1^b1*P2^b2*P3^b3......Pn^bn,(0<=bn<=an),那么这样的话求解约数个数的问题就变化为了求组合数的问题了,就是高中的排列组合,所以约数个数即为(a1+1)(a2+1)(a3+1)……(an+1);

以下是代码:

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long LL;
unordered_map<int,int> primes;

int main()
{
int n;
cin >> n;
LL ans = 1;
while (n -- )
{
int x;
cin >> x;
for(int i = 2;i<=x/i;i++){
while(x%i == 0) {
primes[i] ++ ;
x/=i;
}
}
if(x>1) primes[x] ++;
}
for(auto prime : primes) ans = ans * (prime.second + 1)%mod;
cout << ans << '\n';
return 0;
}

 

 

那么这样的话我们再来看看约数之和怎么算,我们刚刚已经知道了约数的形式是这样的D=P1^b1*P2^b2*P3^b3......Pn^bn,所以所有的约数是不是相当于每个P1,P2,……Pn都出一个指数幂,然后求和;我们可以发现约数之和即为:(P1^0+P1^1+P1^2……+P1^a1)……(Pn^0+Pn^1+Pn^2……+Pn^a1);

 

接下来看代码:

#include<bits/stdc++.h>
#define mod 1000000007

using namespace std;
typedef long long LL;
unordered_map<int,int> primes;

int main()
{
LL ans = 1;
int n;
cin >> n;
while (n -- )
{
int x;
cin >> x;
for(int i = 2;i<=x/i;i++){
while(x % i == 0){
primes[i] ++;
x/=i;
}
}
if(x > 1) primes[x] ++;
}
for(auto prime : primes) {
LL sum = 1;
LL p = 1;
for(int i = 1;i<=prime.second;i++){
sum = (sum*prime.first + 1)%mod;
}
ans = ans*sum%mod;
}
cout << ans << '\n';
return 0;
}