Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/1735.html

1735. Count Ways to Make Array With Product

Level

Hard

Description

You are given a 2D integer array, queries. For each queries[i], where queries[i] = [n_i, k_i], 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 k_i. As the number of ways may be too large, the answer to the i-th query is the number of ways modulo 10^9 + 7.

Return an integer array answer where answer.length == queries.length, and answer[i] is the answer to the i-th query.

Example 1:

Input: queries = [2,6,5,1,73,660]

Output: [4,1,50734910]

Explanation: Each query is independent.

Example 2:

Input: queries = [[1,1],[2,2],[3,3],[4,4],[5,5]]

Output: [1,2,3,10,5]

Constraints:

  • 1 <= queries.length <= 10^4
  • 1 <= n_i, k_i <= 10^4

Solution

First, get all combination numbers for all possible values of n and k. Next, for each query (n, k), do prime factorization for k and calculate the number of ways using the combination numbers and the prime factorization results of k.

  • class Solution {
        int[] primes = new int[14];
        int[] exponents = new int[14];
        int index = 0;
        long[][] combinations = new long[11000][20];
        static final int MODULO = 1000000007;
    
        public int[] waysToFillArray(int[][] queries) {
            for (int i = 0; i < 10500; i++) {
                combinations[i][0] = 1;
                if (i < 15)
                    combinations[i][i] = 1;
                int end = Math.min(i, 15);
                for (int j = 1; j < end; j++)
                    combinations[i][j] = (combinations[i - 1][j - 1] + combinations[i - 1][j]) % MODULO;
            }
            int queriesCount = queries.length;
            int[] ways = new int[queriesCount];
            for (int i = 0; i < queriesCount; i++) {
                int n = queries[i][0], k = queries[i][1];
                long way = 1;
                fact(k);
                for (int j = 1; j <= index; j++)
                    way = way * combinations[n + exponents[j] - 1][exponents[j]] % MODULO;
                ways[i] = (int) way;
            }
            return ways;
        }
    
        public void fact(int n) {
            index = 0;
            for (int i = 2; i * i <= n; i++) {
                if (n % i == 0) {
                    index++;
                    primes[index] = i;
                    exponents[index] = 0;
                    while (n % i == 0) {
                        exponents[index]++;
                        n /= i;
                    }
                }
            }
            if (n != 1) {
                index++;
                primes[index] = n;
                exponents[index] = 1;
            }
        }
    }
    
  • int N = 10020;
    int MOD = 1e9 + 7;
    long f[10020];
    long g[10020];
    vector<int> p[10020];
    
    long qmi(long a, long k, long p) {
        long res = 1;
        while (k != 0) {
            if ((k & 1) == 1) {
                res = res * a % p;
            }
            k >>= 1;
            a = a * a % p;
        }
        return res;
    }
    
    int init = []() {
        f[0] = 1;
        g[0] = 1;
        for (int i = 1; i < N; ++i) {
            f[i] = f[i - 1] * i % MOD;
            g[i] = qmi(f[i], MOD - 2, MOD);
            int x = i;
            for (int j = 2; j <= x / j; ++j) {
                if (x % j == 0) {
                    int cnt = 0;
                    while (x % j == 0) {
                        ++cnt;
                        x /= j;
                    }
                    p[i].push_back(cnt);
                }
            }
            if (x > 1) {
                p[i].push_back(1);
            }
        }
        return 0;
    }();
    
    int comb(int n, int k) {
        return (f[n] * g[k] % MOD) * g[n - k] % MOD;
    }
    
    class Solution {
    public:
        vector<int> waysToFillArray(vector<vector<int>>& queries) {
            vector<int> ans;
            for (auto& q : queries) {
                int n = q[0], k = q[1];
                long long t = 1;
                for (int x : p[k]) {
                    t = t * comb(x + n - 1, n - 1) % MOD;
                }
                ans.push_back(t);
            }
            return ans;
        }
    };
    
  • N = 10020
    MOD = 10**9 + 7
    f = [1] * N
    g = [1] * N
    p = defaultdict(list)
    for i in range(1, N):
        f[i] = f[i - 1] * i % MOD
        g[i] = pow(f[i], MOD - 2, MOD)
        x = i
        j = 2
        while j <= x // j:
            if x % j == 0:
                cnt = 0
                while x % j == 0:
                    cnt += 1
                    x //= j
                p[i].append(cnt)
            j += 1
        if x > 1:
            p[i].append(1)
    
    
    def comb(n, k):
        return f[n] * g[k] * g[n - k] % MOD
    
    
    class Solution:
        def waysToFillArray(self, queries: List[List[int]]) -> List[int]:
            ans = []
            for n, k in queries:
                t = 1
                for x in p[k]:
                    t = t * comb(x + n - 1, n - 1) % MOD
                ans.append(t)
            return ans
    
    
  • const n = 1e4 + 20
    const mod = 1e9 + 7
    
    var f = make([]int, n)
    var g = make([]int, n)
    var p = make([][]int, n)
    
    func qmi(a, k, p int) int {
    	res := 1
    	for k != 0 {
    		if k&1 == 1 {
    			res = res * a % p
    		}
    		k >>= 1
    		a = a * a % p
    	}
    	return res
    }
    
    func init() {
    	f[0], g[0] = 1, 1
    	for i := 1; i < n; i++ {
    		f[i] = f[i-1] * i % mod
    		g[i] = qmi(f[i], mod-2, mod)
    		x := i
    		for j := 2; j <= x/j; j++ {
    			if x%j == 0 {
    				cnt := 0
    				for x%j == 0 {
    					cnt++
    					x /= j
    				}
    				p[i] = append(p[i], cnt)
    			}
    		}
    		if x > 1 {
    			p[i] = append(p[i], 1)
    		}
    	}
    }
    
    func comb(n, k int) int {
    	return (f[n] * g[k] % mod) * g[n-k] % mod
    }
    
    func waysToFillArray(queries [][]int) (ans []int) {
    	for _, q := range queries {
    		n, k := q[0], q[1]
    		t := 1
    		for _, x := range p[k] {
    			t = t * comb(x+n-1, n-1) % mod
    		}
    		ans = append(ans, t)
    	}
    	return
    }
    

All Problems

All Solutions