1735. Count Ways to Make Array With Product
Description
You are given a 2D integer array, queries
. For each queries[i]
, where queries[i] = [ni, ki]
, find the number of different ways you can place positive integers into an array of size ni
such that the product of the integers is ki
. As the number of ways may be too large, the answer to the ith
query is the number of ways modulo 109 + 7
.
Return an integer array answer
where answer.length == queries.length
, and answer[i]
is the answer to the ith
query.
Example 1:
Input: queries = [[2,6],[5,1],[73,660]] Output: [4,1,50734910] Explanation: Each query is independent. [2,6]: There are 4 ways to fill an array of size 2 that multiply to 6: [1,6], [2,3], [3,2], [6,1]. [5,1]: There is 1 way to fill an array of size 5 that multiply to 1: [1,1,1,1,1]. [73,660]: There are 1050734917 ways to fill an array of size 73 that multiply to 660. 1050734917 modulo 109 + 7 = 50734910.
Example 2:
Input: queries = [[1,1],[2,2],[3,3],[4,4],[5,5]] Output: [1,2,3,10,5]
Constraints:
1 <= queries.length <= 104
1 <= ni, ki <= 104
Solutions
Solution: Dynamic Programming + Combinatorics
- Time complexity: O((maxK)log(log(maxK))+(maxN)log(maxN)+queries.length*logk)
- Space complexity: O(maxK+(maxN)log(maxN))
JavaScript
js
/**
* @param {number[][]} queries
* @return {number[]}
*/
const waysToFillArray = function (queries) {
let maxN = 0;
let maxK = 0;
for (const [n, k] of queries) {
maxN = Math.max(n, maxN);
maxK = Math.max(k, maxK);
}
const MODULO = BigInt(10 ** 9 + 7);
const minPrimeSieve = Array.from({ length: maxK + 1 }, (_, index) => index);
const duplicateN = Math.ceil(Math.log2(maxN));
const totalN = maxN + duplicateN;
const nCk = Array.from({ length: totalN + 1 }, () => new Array(duplicateN + 1).fill(1n));
minPrimeSieve[0] = 0;
minPrimeSieve[1] = 0;
for (let num = 2; num ** 2 <= maxK; num++) {
if (minPrimeSieve[num] !== num) continue;
for (let factor = num ** 2; factor <= maxK; factor += num) {
minPrimeSieve[factor] = num;
}
}
for (let a = 2; a <= totalN; a++) {
for (let b = 1; b < Math.min(duplicateN + 1, a); b++) {
nCk[a][b] = nCk[a - 1][b - 1] + nCk[a - 1][b];
}
}
const getPrimeCountMap = num => {
const result = new Map();
while (num > 1) {
const prime = minPrimeSieve[num];
let count = 0;
while (num % prime === 0) {
num /= prime;
count += 1;
}
result.set(prime, count);
}
return result;
};
return queries.map(([n, k]) => {
const primeCountMap = getPrimeCountMap(k);
let ways = 1n;
for (const count of primeCountMap.values()) {
ways = (ways * nCk[n + count - 1][count]) % MODULO;
}
return Number(ways);
});
};