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++
// 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
// 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 |
Python3
# 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#
// 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
// 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
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!