约数之和
原理和约数个数基本相同,用getPrimes()
来求出所有质因子和次数,对于每个 $p_j$ 有$c_j$ ,可以枚举共 $c_j + 1$ 种因子:$1, p_j, p_j ^ 2 …p_j ^ {c_j}$,对其求和用秦九韶算法即可(这个公式看不懂可以直接看getDivisorsSum()
代码中的 $t$ 怎么算的):
$$
s_i = 1 + p_j + p_j ^ 2 +… = 1 + p_j(1 + p_j(1 + …p_j(1 + p_j · 1 )…))
$$
最后求出 $s_i$ 的乘积:
$$
ans = \prod s_i
$$
代码
int getDivisorsSum(vector<int> divisors){
int ans = 1;
unordered_map<int, int> primes;
for (auto it : divisors){
auto vec = getPrimes(it);
for (auto it2 : vec)
primes[it2.first] += it2.second;
}
for (auto it : primes){
int a = it.first, b = it.second;
long long t = 1;
while (b -- ) t = (t * a + 1) % Mod;
ans = ans * t % Mod;
}
return ans;
}
完整代码
#include <bits/stdc++.h>
using namespace std;
const int Mod = 1e9 + 7;
typedef long long ll;
typedef pair<int, int> pii;
vector<pii> getPrimes(int n){
vector<pii> res;
for (int i = 2; i <= n / i; i ++ ){
int a = 0;
while (n % i == 0)
n /= i, a ++ ;
if (a) res.push_back({i, a});
}
if (n > 1) res.push_back({n, 1});
return res;
}
int getDivisorsSum(vector<int> divisors){
int ans = 1;
unordered_map<int, int> primes;
for (auto it : divisors){
auto vec = getPrimes(it);
for (auto it2 : vec)
primes[it2.first] += it2.second;
}
for (auto it : primes){
int a = it.first, b = it.second;
long long t = 1;
while (b -- ) t = (t * a + 1) % Mod;
ans = ans * t % Mod;
}
return ans;
}
int main(){
int n;
cin >> n;
vector<int> a;
while (n -- ){
int x;
cin >> x;
a.push_back(x);
}
cout << getDivisorsSum(a);
return 0;
}