The very well explanation of below approach is here .I was not able to write here due to formatting issues.
// C++ program to find sum of divisors of all the divisors of a natural number.
#include<bits/stdc++.h>
using namespace std;
// Returns sum of divisors of all the divisors
// of n
int sumDivisorsOfDivisors(int n)
{
// Calculating powers of prime factors and
// storing them in a map mp[].
map<int, int> mp;
for (int j=2; j<=sqrt(n); j++)
{
int count = 0;
while (n%j == 0)
{
n /= j;
count++;
}
if (count)
mp[j] = count;
}
// If n is a prime number
if (n != 1)
mp[n] = 1;
// For each prime factor, calculating (p^(a+1)-1)/(p-1)
// and adding it to answer.
int ans = 1;
for (auto it : mp)
{
int pw = 1;
int sum = 0;
for (int i=it.second+1; i>=1; i--)
{
sum += (i*pw);
pw *= it.first;
}
ans *= sum;
}
return ans;
}
// Driven Program
int main()
{
int n = 10;
cout << sumDivisorsOfDivisors(n);
return 0;
}
I am not getting what is happening in this loop instead of adding to ans they are multiplying sum ,how they are calculating (p^(a+1)-1)/(p-1)
and this to ans.can anyone help me with the intuition behind this loop.
I got this from here
for (auto it : mp)
{
int pw = 1;
int sum = 0;
for (int i=it.second+1; i>=1; i--)
{
sum += (i*pw);
pw *= it.first;
}
ans *= sum;
}
First consider this statement:
(p10 + p11 +…+ p1k1) * (p20 + p21 +…+ p2k2)
Now, the divisors of any pa, for p as prime, are p0, p1,……, pa, and sum of diviors will be :
((p10) + (p10 + p11) + .... + (p10 + p11 + ...+ pk1)) * ((p20) + (p20 + p21) + (p20 + p21 + p22) + ... (p20 + p21 + p22 + .. + p2k2))
you can consider the above statement equivalent to bellow statement:
[[p10 * (k1 + 1) + p11 * k1 + p12 * (k1 - 1 ) + .... + (p1k1 * 1) ]] * [[p20 * (k2 + 1) + p21 * (k2) + p22 * (k2 - 1 ) + .... + (p2k2 * 1) ]] in the code that you write in the post, the last statement was implemented.
for example if you consider n = 54 = 33 * 21,
the ans is calculated in this format:
ans = (20 * 2 + 21 * 1) * (30 * 4 + 31 * 3 + 32 * 2 + 33 *1) = 4 * 58 = 232