解题思路

对于每个查询 (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;
    }
}
```

 

Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐