Search code examples
c++algorithmdiscrete-mathematicsnumber-theory

sum of divisors of all divisors of a number


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; 
}

Solution

  • 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