📜  给定数组乘积的因子之和

📅  最后修改于: 2021-05-18 01:04:08             🧑  作者: Mango

给定一个由N个正整数组成的数组arr [] ,任务是找到所有数组元素的乘积因子之和。由于输出可能非常大,请以10 9 + 7模输出。

例子:

天真的方法:解决此问题的最简单方法是遍历数组并计算数组所有元素的乘积,然后计算所获得乘积的所有因子之和。但是这种方法的问题在于,如果数组元素很大,则乘积可能超出整数存储容量的范围,并且将导致错误的输出。
时间复杂度: O(max(N,sqrt(数组元素的乘积)))
辅助空间: O(N)

高效的方法:可以基于以下观察来优化上述方法:

请按照以下步骤解决问题:

  1. 初始化一个整数,例如ans ,以存储数组乘积的所有因子的和。
  2. 初始化一个整数数组,例如count [] ,其中count [i]存储素因i在数组元素乘积中的频率。
  3. 遍历数组count [] ,并检查count [i]是否大于。如果发现为真,则将ans乘以(i (count [i] + 1) )– 1并乘以(i -1)的乘法逆。
  4. 最后,打印在ans中获得的结果

下面是上述方法的实现:

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[0]);
    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[0]);
    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()


输出:
360

时间复杂度: O(N * log(log(N)))
辅助空间: O(N)