Related Articles
Sum of factors of the product of a given array
• Last Updated : 13 Jan, 2021

Given an array arr[] consisting of N positive integers, the task is to find the sum of factors of product of all array elements. Since the output can be very large, print it modulo 109 + 7.

Examples:

Input: arr[] = { 1, 2, 3, 4, 5 }
Output: 360
Explanation:
The product of all array elements = 1 * 2 * 3 * 4 * 5 = 120
All the factors of 120 are { 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 24, 30, 40, 60, 120 }
Therefore, the sum of factors is 360.

Input: arr[] = { 1, 2 }
Output: 3
Explanation:
The product of all array elements = 1 * 2 = 2
All the factors of 2 are { 1, 2 }
Therefore, the sum of factors is 3.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive Approach: The simplest approach to solve this problem is to traverse the array and calculate the product of all elements of the array and calculate the sum of all the factors of the obtained product. But the problem with this approach is that, if the array elements are large, then the product may go out of bounds of the integer storing capacity and it will lead to wrong output.
Time Complexity: O(max(N, sqrt(product of array elements)))
Auxiliary Space: O(N)

Efficient approach: The above approach can be optimized based on the following observations:

If the product of array elements(P) = Then, the sum of factors of P = Follow the steps below to solve the problem:

1. Initialize an integer, say ans, to store the sum of all the factors of the product of the array.
2. Initialize an array of integer, say count[], where count[i] stores the frequency of prime factors i, in product of the array elements.
3. Traverse the array count[], and check if count[i] is greater than zero or not. If found to be true, then multiply ans by (i(count[i] + 1)) – 1 and multiplicative inverse of (i -1)
4. Finally, print the result obtained in ans

Below is the implementation of the above approach:

## C

 // C program to implement  // the above approach     #include  #define size 1000100  #define inverse(a) power(a, mod - 2)  typedef long long int ll;  const ll mod = ((ll)(1e9 + 7));     // Stores minimum prime  // factorizaton of a number  int spf[size] = { 0 };     // Function to add two numbers  static inline ll add(ll a, ll b)  {      return (a % mod + b % mod) % mod;  }     // Function to substract two numbers  static inline ll sub(ll a, ll b)  {      return add(mod, a - b) % mod;  }     // Function to multiply two numbers  static inline ll mul(ll a, ll b)  {      return (a % mod * b % mod) % mod;  }     // Function to calculate  // x to the power y  ll power(ll x, ll y)  {         // Stores  x ^ y      ll res = 1;      for (res = 1; y > 0;           x = (x * x) % mod, y >>= 1) {             // If y is odd          if (y & 1) {                 // Update result              res = (res * x) % mod;          }      }      return res;  }     // Function to find the smallest prime factor  // of numbers in the range [1, 1000100]  void sieve()  {         // Update the smallest prime factor of      // all the numbers which is divisible by 2      for (int i = 2; i < size; i += 2) {             // Update spf[i]          spf[i] = 2;      }      for (int i = 3; i < size; i += 2)          spf[i] = i;         // Calculate the smallest prime factor      // of all the numbers in the range [3, 1000100]      for (int i = 3; i * i < size; i += 2)          if (spf[i] == i)              for (int j = i * i; j < size; j += i)                  spf[j] = i;  }     // Fucntion to find the sum of factors of  // product of all array elements  long long int sumof_factors(int a[], int n)  {         // Stores the sum of factors of      // product of all array elements      ll ans = 1;         // count[i]: Stores frequency of      // prime factor i in product of      // all the array elements      ll count[size] = { 0 };         // Traverse the array      for (int i = 0; i < n; i++) {             // Calculate the prime factor          // of a[i]          while (a[i] > 1) {                 // Update frequency of              // prime factor spf[a[i]]              count[spf[a[i]]]++;                 // Update a[i]              a[i] /= spf[a[i]];          }      }         // Traverse the array, count[]      for (ll i = 0; i < size; i++)             // If frequency of prime factor i in          // product of array elements          // greater than 0          if (count[i] > 0) {                 // Calculate (i^(count[i]+1))-1 and              // multiplicative inverse of (i -1)              ll num1 = sub(power(i, count[i] + 1), 1);              ll num2 = inverse(i - 1);              ans = mul(ans, mul(num1, num2));          }         return ans;  }     // Driver Code  int main()  {      sieve();      int arr[] = { 1, 3, 2, 5, 4 };      int N = sizeof(arr) / sizeof(arr);      ll res = sumof_factors(arr, N);      printf("%lld\n", res);      return 0;  }

## C++

 // C++ program to implement  // the above approach     #include  using namespace std;     #define size 1000100  #define inverse(a) power(a, mod - 2)     typedef long long int ll;  const ll mod = ((ll)(1e9 + 7));     // Stores minimum prime  // factorizaton of a number  int spf[size] = { 0 };     // Function to add two numbers  static inline ll add(ll a, ll b)  {      return (a % mod + b % mod) % mod;  }     // Function to subtract two numbers  static inline ll sub(ll a, ll b)  {      return add(mod, a - b) % mod;  }     // Function to multiply two numbers  static inline ll mul(ll a, ll b)  {      return (a % mod * b % mod) % mod;  }     // Function to calculate  // x to the power y  ll power(ll x, ll y)  {         // Stores  x ^ y      ll res = 1;      for (res = 1; y > 0;           x = (x * x) % mod, y >>= 1) {             // If y is odd          if (y & 1) {                 // Update result              res = (res * x) % mod;          }      }      return res;  }     // Function to find the smallest prime factor  // of numbers in the range [1, 1000100]  void sieve()  {         // Update the smallest prime factor of      // all the numbers which is divisible by 2      for (int i = 2; i < size; i += 2) {             // Update spf[i]          spf[i] = 2;      }      for (int i = 3; i < size; i += 2)          spf[i] = i;         // Calculate the smallest prime factor      // of all the numbers in the range [3, 1000100]      for (int i = 3; i * i < size; i += 2)          if (spf[i] == i)              for (int j = i * i; j < size; j += i)                  spf[j] = i;  }     // Function to calculate sum of factors  // of product of the given array  long long int sumof_factors(int a[], int n)  {         // Stores the sum of factors of      // product of all array elements      ll ans = 1;         // count[i]: Stores frequency of      // prime factor i in product of      // all the array elements      ll count[size] = { 0 };         // Traverse the array      for (int i = 0; i < n; i++) {             // Calculate the prime factor          // of a[i]          while (a[i] > 1) {                 // Update frequency of              // prime factor spf[a[i]]              count[spf[a[i]]]++;                 // Update a[i]              a[i] /= spf[a[i]];          }      }         // Traverse the array, count[]      for (ll i = 0; i < size; i++)             // If frequency of prime factor i in          // product of array elements          // greater than 0          if (count[i] > 0) {                 // Calculate (i^(count[i]+1))-1 and              // multiplicative inverse of (i -1)              ll num1 = sub(power(i, count[i] + 1), 1);              ll num2 = inverse(i - 1);              ans = mul(ans, mul(num1, num2));          }         return ans;  }     // Driver Code  int main()  {      sieve();      int arr[] = { 1, 3, 2, 5, 4 };      int N = sizeof(arr) / sizeof(arr);      ll res = sumof_factors(arr, N);      cout << res;      return 0;  }

## Java

 // Java program to implement  // the above approach     import java.util.HashMap;  import java.util.Map;  class GFG {         static final long mod = (int)(1e9 + 7);      static final int size = (int)(1e6 + 100);         // Function to substract two numbers      static final long sub(long a, long b)      {          return (mod + a % mod - b % mod) % mod;      }         // Function to multiply two numbers      static final long mul(long a, long b)      {          return (a % mod * b % mod) % mod;      }         // Function to calculate      // x to the power y      static long power(long x, long y)      {          // Stores  x ^ y          long res = 1;          for (res = 1; y > 0;               x = (x * x) % mod, y >>= 1) {                 // If y is odd              if ((y & 1) == 1) {                     // Update result                  res = (res * x) % mod;              }          }          return res;      }         // Function to find inverse      // of a mod 1e9 + 7      static long inverse(long a)      {          return power(a, mod - 2);      }         // Stores minimum prime      // factorizaton of a number      static int spf[] = new int[size];         // Function to find the smallest prime factor      // of numbers in the range [1, 1000100]      static void sieve()      {          for (int i = 1; i < size; i += 2)              spf[i] = i;          for (int i = 2; i < size; i += 2)              spf[i] = 2;          for (int i = 3; i * i < size; i += 2)              if (spf[i] == i)                  for (int j = i * i; j < size; j += i)                      spf[j] = i;      }         // Function to calculate sum of factors      // of product of the given array      static long sumof_factors(int a[], int n)      {             // Traverse the array          for (int i = 0; i < n; i++)              if (a[i] == 0)                  return 0;             // Stores the sum of factors of          // product of all array elements          long ans = 1;             // count[i]: Stores frequency of          // prime factor i in product of          // all the array elements          Map count              = new HashMap();             // Traverse the array          for (int num : a) {                 // Calculate the prime factor              // of a[i]              while (num > 1) {                  int temp = 0;                  try {                      temp = count.get(spf[num]);                  }                  catch (Exception e) {                      temp = 0;                  }                     // Update frequency of                  // prime factor spf[a[i]]                  count.put(spf[num], temp + 1);                     // Update num                  num /= spf[num];              }          }             for (Map.Entry i :               count.entrySet()) {                 // Calculate (i^(count[i]+1))-1 and              // multiplicative inverse of (i -1)              long num1 = sub(                  power(i.getKey(), i.getValue() + 1), 1);              long num2 = inverse(i.getKey() - 1);                 ans = mul(ans, mul(num1, num2));          }             return ans;      }         // Driver Code      public static void main(String[] args)      {          sieve();          int n = 5;          int a[] = { 1, 3, 2, 5, 4 };          System.out.println(sumof_factors(a, n));      }  }

## Python3

 # Python program to implement  # the above approach     from collections import defaultdict  from math import sqrt        # Function to find the smallest prime factor  # of numbers in the range [1, 1000100]  def computeSPF(size):             # Stores smallest prime      # factorizaton of a number      spf = [i for i in range(size)]                    # Update the smallest prime factor of       # all the numbers which is divisible by 2      for i in range(2, size, 2):          spf[i] = 2                # Calculate the smallest prime factor      # of all the numbers in the range [3, 1000100]          for i in range(3, int(sqrt(size))+1, 2):          if spf[i] == i:              for j in range(i * i, size, i):                  spf[j] = i      return spf     # Function to calculate sum of factors  # of product of the given array  def sumof_factors(a, n, spf, mod):                    # Traverse the array      if 0 in a:          return 0     count = defaultdict(int)                    # Stores the sum of factors of      # product of all array elements      ans = 1            # Traverse the array      for num in a:                     # Calculate the prime factor          # of a[i]          while num > 1:                                            # Update frequency of              # prime factor spf[a[i]]              count[spf[num]] += 1             num //= spf[num]                     # Traverse the array, count[]        for i in count:          num1 = pow(i, count[i]+1, mod) - 1         num2 = pow(i-1, mod-2, mod)          ans = (ans * num1 * num2) % mod      return ans        # Driver Code  def main():      spf = computeSPF(10**6)      mod = 10**9 + 7     n = 4     a = [1, 3, 2, 5]      ans = sumof_factors(a, n, spf, mod)      print(ans)        main()

Output:

360


Time Complexity: O(N * log(log(N)))
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up
Recommended Articles
Page :