DeepSeek LeetCode 1735.生成乘积数组的方案数 public int[] waysToFillArray(int[][] queries)
预处理阶乘和逆元,最大参数为 max_n + max_e,其中 max_e ≤ 14(因为 k \le 10^4)。2. 独立分配:每个质因子 p_i 的指数 e_i 需要分配到 n 个位置上(每个位置分配非负整数,和为 e_i)。对于每个查询 (n, k),需要计算长度为 n 的正整数数组,使得数组元素的乘积等于 k 的方案数。分配方案数(隔板法)为组合数\binom{e_i + n - 1}{
解题思路
对于每个查询 (n, k),需要计算长度为 n 的正整数数组,使得数组元素的乘积等于 k 的方案数。
1. 质因数分解:将 k 分解为质因数的幂的乘积:
k = p_1^{e_1} \cdot p_2^{e_2} \cdots p_m^{e_m} 。
2. 独立分配:每个质因子 p_i 的指数 e_i 需要分配到 n 个位置上(每个位置分配非负整数,和为 e_i)。
分配方案数(隔板法)为组合数 \binom{e_i + n - 1}{n - 1} 。
3. 乘法原理:不同质因子的分配相互独立,总方案数为:
\prod_{i=1}^{m} \binom{e_i + n - 1}{n - 1}
4. 模运算:结果对 10^9+7 取模。
算法步骤
· 预处理阶乘和逆元,最大参数为 max_n + max_e,其中 max_e ≤ 14(因为 k \le 10^4)。
· 对每个查询:
· 分解 k 得到每个质因子的指数 e。
· 累乘组合数 C(e + n - 1, n - 1)。
· 返回结果数组。
复杂度
· 时间:每个查询的分解复杂度为 O(\sqrt{k}),组合数计算 O(1)。
· 空间:O(\max\_n + \max\_e)。
Java代码
```java
class Solution {
private static final int MOD = 1_000_000_007;
private static final int MAX_N = 10000;
private static final int MAX_E = 14; // 2^14 > 10000
private static final int MAX_FACT = MAX_N + MAX_E; // 10014
private static long[] fact = new long[MAX_FACT + 1];
private static long[] invFact = new long[MAX_FACT + 1];
private static boolean precomputed = false;
private static void precompute() {
if (precomputed) return;
fact[0] = 1;
for (int i = 1; i <= MAX_FACT; i++) {
fact[i] = fact[i - 1] * i % MOD;
}
invFact[MAX_FACT] = modInverse(fact[MAX_FACT]);
for (int i = MAX_FACT - 1; i >= 0; i--) {
invFact[i] = invFact[i + 1] * (i + 1) % MOD;
}
precomputed = true;
}
private static long modInverse(long a) {
return pow(a, MOD - 2);
}
private static long pow(long a, long b) {
long res = 1;
a %= MOD;
while (b > 0) {
if ((b & 1) == 1) res = res * a % MOD;
a = a * a % MOD;
b >>= 1;
}
return res;
}
private static long comb(int a, int b) {
if (b < 0 || b > a) return 0;
return fact[a] * invFact[b] % MOD * invFact[a - b] % MOD;
}
public int[] waysToFillArray(int[][] queries) {
precompute();
int q = queries.length;
int[] ans = new int[q];
for (int i = 0; i < q; i++) {
int n = queries[i][0];
int k = queries[i][1];
long ways = 1;
int temp = k;
// 质因数分解
for (int p = 2; p * p <= temp; p++) {
if (temp % p == 0) {
int exp = 0;
while (temp % p == 0) {
temp /= p;
exp++;
}
ways = ways * comb(exp + n - 1, n - 1) % MOD;
}
}
if (temp > 1) { // 剩余质数,指数为1
ways = ways * comb(1 + n - 1, n - 1) % MOD; // 即 C(n, n-1) = n
}
ans[i] = (int) ways;
}
return ans;
}
}
```
更多推荐




所有评论(0)