给定一个由N个正整数组成的数组arr [] ,任务是找到所有数组元素的乘积因子之和。由于输出可能非常大,请以10 9 + 7模输出。
例子:
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.
天真的方法:解决此问题的最简单方法是遍历数组并计算数组所有元素的乘积,然后计算所获得乘积的所有因子之和。但是这种方法的问题在于,如果数组元素很大,则乘积可能超出整数存储容量的范围,并且将导致错误的输出。
时间复杂度: O(max(N,sqrt(数组元素的乘积)))
辅助空间: O(N)
高效的方法:可以基于以下观察来优化上述方法:
If the product of array elements(P) =
Then, the sum of factors of P =
请按照以下步骤解决问题:
- 初始化一个整数,例如ans ,以存储数组乘积的所有因子的和。
- 初始化一个整数数组,例如count [] ,其中count [i]存储素因i在数组元素乘积中的频率。
- 遍历数组count [] ,并检查count [i]是否大于零。如果发现为真,则将ans乘以(i (count [i] + 1) )– 1并乘以(i -1)的乘法逆。
- 最后,打印在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)