利用算術基本定理求解約數個數 + 約數之和
先前我們已經介紹過了怎麼判斷質數和約數,現在我們對於約數的個數和約數之和也要進行求解,而求解的方法就是根據算術基本定理來的!
先介紹一下什麼是算術基本定理:
算術基本定理可表述為:任何一個大於1的自然數 N,如果N不為質數,那麼N可以唯一分解成有限個質數的乘積N=P1^a1*P2^a2*P3^a3......Pn^an,這裡P1<P2<P3......<Pn均為質數,其中指數ai是正整數。這樣的分解稱為 N 的標準分解式。
那麼一直這個之後我們是不是可以知道這個自然數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;
}