Given an integer array arr[] of length N and an integer K, the task is to count the number of possible arrays of length K such that the product of all elements of that array is equal to the product of all elements of the given array arr[]. Since the answer can be very large, return the answer modulo 109 + 7. Examples:
Input: arr[] = {2, 3}, K = 3 Output: 9 The product of the elements of the array is 2 * 3 = 6. And there are 9 such arrays of length 3 possible, product of whose elements is 6, {1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}, {1, 1, 6}, {1, 6, 1} and {6, 1, 1}. Input: arr[] = {1, 3, 5, 2}, K = 3 Output: 27
Prerequisites: Prime Factorization, Compute nCr % p Approach: Let the product of all the elements of arr[] be X. X can be represented by it’s prime factorization, i.e., X = p1c1*p2c2*…*prcr where pi are primes and ci are some non-negative coefficients. Let the K sized array be B[]. Instead of finding actual integers for B[], find the prime factorization for each Bi. The prime factorization of any number from B[] can’t have any prime except the primes which are factor of X because X % Bi should be equal to zero.
Thus, Bi = p1c1i * p2c2i * … * prcri with cij >= 0. And so, B1 * B2 * … Bk = p1(c11 + c12 + … + c1k) * p2(c21 + c22 + … + c2k) * … * pr(cr1 + cr2 + … + crk). Equating B1 * B2 * … Bk = X = p1c1*p2c2*…*prcr, we get r equations. c11 + c12 + … + c1k = c1 c21 + c22 + … + c2k = c2 . . . cr1 + cr2 + … + crk = cr where cij >= 0
Answer to ith equation is equal to the number of ways of distributing ci identical balls in K distinguishable boxes and so it is ci + K – 1 C K – 1. All the equations are independent, and so final answer = multiplication of answer to each equation. Below is the implementation of the above approach:
// C++ implementation of the approach #include <bits/stdc++.h> using namespace std;
#define ll long long #define MAXN (ll)(1e5 + 1) #define mod (ll)(1e9 + 7) // To store the smallest prime factor // for every number ll spf[MAXN]; // Initialize map to store // count of prime factors map<ll, ll> cnt; // Function to calculate SPF(Smallest Prime Factor) // for every number till MAXN void sieve()
{ spf[1] = 1;
for ( int i = 2; i < MAXN; i++)
// Marking smallest prime factor for every
// number to be itself
spf[i] = i;
// Separately marking spf for every even
// number as 2
for ( int i = 4; i < MAXN; i += 2)
spf[i] = 2;
for ( int i = 3; i * i < MAXN; i++) {
// Checking if i is prime
if (spf[i] == i) {
// Marking SPF for all numbers divisible by i
for ( int j = i * i; j < MAXN; j += i)
// Marking spf[j] if it is not
// previously marked
if (spf[j] == j)
spf[j] = i;
}
}
} // Function to factorize using spf // and store in cnt void factorize(ll f)
{ while (f > 1) {
ll x = spf[f];
while (f % x == 0) {
cnt[x]++;
f /= x;
}
}
} // Function to return n! % p ll factorial(ll n, ll p) { // Initialize result
ll res = 1;
for ( int i = 2; i <= n; i++)
res = (res * i) % p;
return res;
} // Iterative Function to calculate (x^y)%p // in O(log y) ll power(ll x, ll y, ll p) { // Initialize result
ll res = 1;
// Update x if it is >= p
x = x % p;
while (y > 0) {
// If y is odd, multiply x with result
if (y & 1)
res = (res * x) % p;
// y must be even now
// y = y/2
y = y >> 1;
x = (x * x) % p;
}
return res;
} // Function that returns n^(-1) mod p ll modInverse(ll n, ll p) { return power(n, p - 2, p);
} // Function that returns nCr % p // using Fermat's little theorem ll nCrModP(ll n, ll r, ll p) { // Base case
if (r == 0)
return 1;
// Fill factorial array so that we
// can find all factorial of r, n
// and n - r
ll fac[n + 1];
fac[0] = 1;
for ( int i = 1; i <= n; i++)
fac[i] = fac[i - 1] * i % p;
return (fac[n] * modInverse(fac[r], p) % p
* modInverse(fac[n - r], p) % p)
% p;
} // Function to return the count the number of possible // arrays mod P of length K such that the product of all // elements of that array is equal to the product of // all elements of the given array of length N ll countArrays(ll arr[], ll N, ll K, ll P) { // Initialize result
ll res = 1;
// Call sieve to get spf
sieve();
for ( int i = 0; i < N; i++) {
// Factorize arr[i], count and
// store its factors in cnt
factorize(arr[i]);
}
for ( auto i : cnt) {
int ci = i.second;
res = (res * nCrModP(ci + K - 1, K - 1, P)) % P;
}
return res;
} // Driver code int main()
{ ll arr[] = { 1, 3, 5, 2 }, K = 3;
ll N = sizeof (arr) / sizeof (arr[0]);
cout << countArrays(arr, N, K, mod);
return 0;
} |
// Java implementation of the approach import java.util.HashMap;
class GFG
{ static long MAXN = 100001L, mod = 1000000007L;
// To store the smallest prime factor
// for every number
static long [] spf = new long [( int ) MAXN];
// Initialize map to store
// count of prime factors
static HashMap<Long, Long> cnt = new HashMap<>();
// Function to calculate SPF(Smallest Prime Factor)
// for every number till MAXN
public static void sieve()
{
spf[ 1 ] = 1 ;
for ( int i = 2 ; i < MAXN; i++)
// Marking smallest prime factor for every
// number to be itself
spf[i] = i;
// Separately marking spf for every even
// number as 2
for ( int i = 4 ; i < MAXN; i += 2 )
spf[i] = 2 ;
for ( int i = 3 ; i * i < MAXN; i++)
{
// Checking if i is prime
if (spf[i] == i) {
// Marking SPF for all numbers divisible by i
for ( int j = i * i; j < MAXN; j += i)
// Marking spf[j] if it is not
// previously marked
if (spf[j] == j)
spf[j] = i;
}
}
}
// Function to factorize using spf
// and store in cnt
public static void factorize( long f)
{
while (f > 1 )
{
long x = spf[( int ) f];
while (f % x == 0 )
{
if (cnt.containsKey(x))
{
long z = cnt.get(x);
cnt.put(x, ++z);
}
else
cnt.put(x, ( long ) 1 );
f /= x;
}
}
}
// Function to return n! % p
public static long factorial( long n, long p)
{
// Initialize result
long res = 1 ;
for ( long i = 2 ; i <= n; i++)
res = (res * i) % p;
return res;
}
// Iterative Function to calculate (x^y)%p
// in O(log y)
public static long power( long x, long y, long p)
{
// Initialize result
long res = 1 ;
// Update x if it is >= p
x = x % p;
while (y > 0 ) {
// If y is odd, multiply x with result
if (y % 2 == 1 )
res = (res * x) % p;
// y must be even now
// y = y/2
y = y >> 1 ;
x = (x * x) % p;
}
return res;
}
// Function that returns n^(-1) mod p
public static long modInverse( long n, long p)
{
return power(n, p - 2 , p);
}
// Function that returns nCr % p
// using Fermat's little theorem
public static long nCrModP( long n, long r, long p)
{
// Base case
if (r == 0 )
return 1 ;
// Fill factorial array so that we
// can find all factorial of r, n
// and n - r
long [] fac = new long [( int ) n + 1 ];
fac[ 0 ] = 1 ;
for ( int i = 1 ; i <= n; i++)
fac[i] = fac[i - 1 ] * i % p;
return (fac[( int ) n] * modInverse(fac[( int ) r], p) % p *
modInverse(fac[( int ) (n - r)], p) % p) % p;
}
// Function to return the count the number of possible
// arrays mod P of length K such that the product of all
// elements of that array is equal to the product of
// all elements of the given array of length N
public static long countArrays( long [] arr,
long N, long K, long P)
{
// Initialize result
long res = 1 ;
// Call sieve to get spf
sieve();
for ( int i = 0 ; i < N; i++)
{
// Factorize arr[i], count and
// store its factors in cnt
factorize(arr[i]);
}
for (HashMap.Entry<Long, Long> entry : cnt.entrySet())
{
long ci = entry.getValue();
res = (res * nCrModP(ci + K - 1 , K - 1 , P)) % P;
}
return res;
}
// Driver code
public static void main(String[] args)
{
long [] arr = { 1 , 3 , 5 , 2 };
long K = 3 ;
long N = arr.length;
System.out.println(countArrays(arr, N, K, mod));
}
} // This code is contributed by // sanjeev2552 |
# Python 3 implementation of the approach from math import sqrt
MAXN = 100001
mod = 1000000007
# To store the smallest prime factor # for every number spf = [ 0 for i in range (MAXN)]
# Initialize map to store # count of prime factors cnt = {i: 0 for i in range ( 10 )}
# Function to calculate SPF(Smallest Prime Factor) # for every number till MAXN def sieve():
spf[ 1 ] = 1
for i in range ( 2 ,MAXN):
# Marking smallest prime factor for every
# number to be itself
spf[i] = i
# Separately marking spf for every even
# number as 2
for i in range ( 4 ,MAXN, 2 ):
spf[i] = 2
for i in range ( 3 , int (sqrt(MAXN)) + 1 , 1 ):
# Checking if i is prime
if (spf[i] = = i):
# Marking SPF for all numbers divisible by i
for j in range (i * i,MAXN,i):
# Marking spf[j] if it is not
# previously marked
if (spf[j] = = j):
spf[j] = i
# Function to factorize using spf # and store in cnt def factorize(f):
while (f > 1 ):
x = spf[f]
while (f % x = = 0 ):
cnt[x] + = 1
f = int (f / x)
# Function to return n! % p def factorial(n,p):
#Initialize result
res = 1
for i in range ( 2 ,n + 1 , 1 ):
res = (res * i) % p
return res
# Iterative Function to calculate (x^y)%p # in O(log y) def power(x, y, p):
# Initialize result
res = 1
# Update x if it is >= p
x = x % p
while (y > 0 ):
# If y is odd, multiply x with result
if (y & 1 ):
res = (res * x) % p
# y must be even now
# y = y/2
y = y >> 1
x = (x * x) % p
return res
# Function that returns n^(-1) mod p def modInverse(n,p):
return power(n, p - 2 , p)
# Function that returns nCr % p # using Fermat's little theorem def nCrModP(n,r,p):
# Base case
if (r = = 0 ):
return 1
# Fill factorial array so that we
# can find all factorial of r, n
# and n - r
fac = [ 0 for i in range (n + 1 )]
fac[ 0 ] = 1
for i in range ( 1 ,n + 1 , 1 ):
fac[i] = fac[i - 1 ] * i % p
return (fac[n] * modInverse(fac[r], p) % p *
modInverse(fac[n - r], p) % p) % p
# Function to return the count the number of possible # arrays mod P of length K such that the product of all # elements of that array is equal to the product of # all elements of the given array of length N def countArrays(arr,N,K,P):
# Initialize result
res = 1
# Call sieve to get spf
sieve()
for i in range (N):
# Factorize arr[i], count and
# store its factors in cnt
factorize(arr[i])
for key,value in cnt.items():
ci = value
res = (res * nCrModP(ci + K - 1 , K - 1 , P)) % P
return res
# Driver code if __name__ = = '__main__' :
arr = [ 1 , 3 , 5 , 2 ]
K = 3
N = len (arr)
print (countArrays(arr, N, K, mod))
# This code is contributed by # Surendra_Gangwar |
// C# implementation of the approach using System;
using System.Collections.Generic;
class GFG
{ static long MAXN = 100001L, mod = 1000000007L;
// To store the smallest prime factor
// for every number
static long [] spf = new long [( int ) MAXN];
// Initialize map to store
// count of prime factors
static Dictionary< long ,
long > cnt = new Dictionary< long ,
long >();
// Function to calculate SPF(Smallest Prime Factor)
// for every number till MAXN
public static void sieve()
{
spf[1] = 1;
for ( int i = 2; i < MAXN; i++)
// Marking smallest prime factor for every
// number to be itself
spf[i] = i;
// Separately marking spf for every even
// number as 2
for ( int i = 4; i < MAXN; i += 2)
spf[i] = 2;
for ( int i = 3; i * i < MAXN; i++)
{
// Checking if i is prime
if (spf[i] == i)
{
// Marking SPF for all numbers divisible by i
for ( int j = i * i; j < MAXN; j += i)
// Marking spf[j] if it is not
// previously marked
if (spf[j] == j)
spf[j] = i;
}
}
}
// Function to factorize using spf
// and store in cnt
public static void factorize( long f)
{
while (f > 1)
{
long x = spf[( int ) f];
while (f % x == 0)
{
if (cnt.ContainsKey(x))
{
long z = cnt[x];
cnt[x] = ++z;
}
else
cnt.Add(x, ( long ) 1);
f /= x;
}
}
}
// Function to return n! % p
public static long factorial( long n, long p)
{
// Initialize result
long res = 1;
for ( long i = 2; i <= n; i++)
res = (res * i) % p;
return res;
}
// Iterative Function to calculate (x^y)%p
// in O(log y)
public static long power( long x, long y, long p)
{
// Initialize result
long res = 1;
// Update x if it is >= p
x = x % p;
while (y > 0)
{
// If y is odd, multiply x with result
if (y % 2 == 1)
res = (res * x) % p;
// y must be even now
// y = y/2
y = y >> 1;
x = (x * x) % p;
}
return res;
}
// Function that returns n^(-1) mod p
public static long modInverse( long n, long p)
{
return power(n, p - 2, p);
}
// Function that returns nCr % p
// using Fermat's little theorem
public static long nCrModP( long n, long r, long p)
{
// Base case
if (r == 0)
return 1;
// Fill factorial array so that we
// can find all factorial of r, n
// and n - r
long [] fac = new long [( int ) n + 1];
fac[0] = 1;
for ( int i = 1; i <= n; i++)
fac[i] = fac[i - 1] * i % p;
return (fac[( int ) n] * modInverse(fac[( int ) r], p) % p *
modInverse(fac[( int ) (n - r)], p) % p) % p;
}
// Function to return the count the number of possible
// arrays mod P of length K such that the product of all
// elements of that array is equal to the product of
// all elements of the given array of length N
public static long countArrays( long [] arr,
long N, long K, long P)
{
// Initialize result
long res = 1;
// Call sieve to get spf
sieve();
for ( int i = 0; i < N; i++)
{
// Factorize arr[i], count and
// store its factors in cnt
factorize(arr[i]);
}
foreach (KeyValuePair< long , long > entry in cnt)
{
long ci = entry.Value;
res = (res * nCrModP(ci + K - 1, K - 1, P)) % P;
}
return res;
}
// Driver code
public static void Main(String[] args)
{
long [] arr = { 1, 3, 5, 2 };
long K = 3;
long N = arr.Length;
Console.WriteLine(countArrays(arr, N, K, mod));
}
} // This code is contributed by PrinciRaj1992 |
// JavaScript implementation of the approach let MAXN = 100001n let mod = 1000000007n // To store the smallest prime factor // for every number let spf = new Array(MAXN).fill(0n)
// Initialize map to store // count of prime factors let cnt = {} for ( var i = 0n; i < 10; i++)
cnt[i] = 0n;
// Function to calculate SPF(Smallest Prime Factor) // for every number till MAXN function sieve()
{ spf[1] = 1n
for ( var i = 2n; i < MAXN; i++)
// Marking smallest prime factor for every
// number to be itself
spf[i] = i
// Separately marking spf for every even
// number as 2
for ( var i = 4n; i < MAXN; i += 2n)
spf[i] = 2n
for ( var i = 3n; i * i < MAXN; i++)
{
// Checking if i is prime
if (spf[i] == i)
{
// Marking SPF for all numbers divisible by i
for ( var j = i * i; j < MAXN; j += i)
// Marking spf[j] if it is not
// previously marked
if (spf[j] == j)
spf[j] = i
}
}
} // Function to factorize using spf // and store in cnt function factorize(f)
{ while (f > 1n)
{
let x = spf[f]
while (f % x == 0n)
{
cnt[x] += 1n
f = (f - (f % x)) / x
}
}
} // Function to return n! % p function factorial(n,p)
{ //Initialize result
let res = 1n
for ( var i = 2n; i <= n; i++)
res = (res * i) % p
return res
} // Iterative Function to calculate (x^y)%p // in O(log y) function power(x, y, p)
{ // Initialize result
let res = 1n
// Update x if it is >= p
x = x % p
while (y > 0n)
{
// If y is odd, multiply x with result
if (y & 1n)
res = (res * x) % p
// y must be even now
// y = y/2
y = y >> 1n
x = (x * x) % p
}
return res
} // Function that returns n^(-1) mod p function modInverse(n,p)
{ return power(n, p - 2n, p)
} // Function that returns nCr % p // using Fermat's little theorem function nCrModP(n,r,p)
{ // Base case
if (r == 0n)
return 1n
// Fill factorial array so that we
// can find all factorial of r, n
// and n - r
let fac = new Array(n + 1n).fill(0n)
fac[0] = 1n
for ( var i = 1n; i <= n; i++)
fac[i] = fac[i - 1n] * i % p
return (fac[n] * modInverse(fac[r], p) % p *
modInverse(fac[n - r], p) % p)% p
} // Function to return the count the number of possible // arrays mod P of length K such that the product of all // elements of that array is equal to the product of // all elements of the given array of length N function countArrays(arr,N,K,P)
{ // Initialize result
let res = 1n
// Call sieve to get spf
sieve()
for ( var i = 0n; i < N; i++)
// Factorize arr[i], count and
// store its factors in cnt
factorize(arr[i])
for ( const [key,value] of Object.entries(cnt))
{
let ci = value
res = (res * nCrModP(ci + K - 1n, K - 1n, P)) % P
}
return res
} // Driver code let arr = [1n, 3n, 5n, 2n] let K = 3n let N = arr.length console.log(countArrays(arr, N, K, mod)) // This code is contributed by // phasing17 |
27