列表

详情


1735. 生成乘积数组的方案数

给你一个二维整数数组 queries ,其中 queries[i] = [ni, ki] 。第 i 个查询 queries[i] 要求构造长度为 ni 、每个元素都是正整数的数组,且满足所有元素的乘积为 ki ,请你找出有多少种可行的方案。由于答案可能会很大,方案数需要对 109 + 7 取余

请你返回一个整数数组 answer,满足 answer.length == queries.length ,其中 answer[i]是第 i 个查询的结果。

 

示例 1:

输入:queries = [[2,6],[5,1],[73,660]]
输出:[4,1,50734910]
解释:每个查询之间彼此独立。
[2,6]:总共有 4 种方案得到长度为 2 且乘积为 6 的数组:[1,6],[2,3],[3,2],[6,1]。
[5,1]:总共有 1 种方案得到长度为 5 且乘积为 1 的数组:[1,1,1,1,1]。
[73,660]:总共有 1050734917 种方案得到长度为 73 且乘积为 660 的数组。1050734917 对 109 + 7 取余得到 50734910 。

示例 2 :

输入:queries = [[1,1],[2,2],[3,3],[4,4],[5,5]]
输出:[1,2,3,10,5]

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: vector<int> waysToFillArray(vector<vector<int>>& queries) { } };

rust 解法, 执行用时: 48 ms, 内存消耗: 4.1 MB, 提交时间: 2023-10-25 22:52:16

impl Solution {

    pub fn ways_to_fill_array(queries: Vec<Vec<i32>>) -> Vec<i32> {
        fn factor(mut n: i32) -> Vec<usize> {
            let mut ans = vec![];
            for i in 2..2+(n as f64).sqrt() as i32 {
                let mut c = 0;
                while n % i == 0 {
                    c += 1;
                    n /= i;
                }
                if c > 0 {
                    ans.push(c);
                }
                if n == 1 {
                    break;
                }
            }
            if n > 1 {
                ans.push(1);
            }
            ans
        }

        let mut comb = vec![vec![0; 15]; 10015];
        let mo = 1_000_000_007;
        comb[0][0] = 1;
        for i in 1..comb.len() {
            comb[i][0] = 1;
            for j in 1..comb[i].len() {
                comb[i][j] = (comb[i - 1][j] + comb[i - 1][j - 1]) % mo;
            }
        }
        let mut ans = vec![];
        for q in queries {
            let mut bb = 1i64;
            for a in factor(q[1]) {
                bb = comb[a + q[0] as usize - 1][a] * bb % mo;
            }
            ans.push(bb as i32);
        }
        ans
    }
}

rust 解法, 执行用时: 212 ms, 内存消耗: 4.5 MB, 提交时间: 2023-10-25 22:52:01

use std::collections::{BinaryHeap, HashMap, HashSet};
impl Solution {


    pub fn ways_to_fill_array(queries: Vec<Vec<i32>>) -> Vec<i32> {
        fn decomposePrimeFactors() -> Vec<HashMap<usize, usize>> {
            let size = 10000;
            let mut ps = vec![HashMap::new(); size + 1];
            for i in 2..ps.len() {
                if ps[i].is_empty() {
                    ps[i].insert(i, 1);
                    let mut t = 2;
                    while i * t <= size {
                        if ps[i * t].is_empty() {
                            ps[i * t].insert(i, t);
                        }
                        t += 1;
                    }
                } else {
                    let (x, c) = ps[i].drain().next().unwrap();
                    ps[i].insert(x, 1);
                    let b = ps[c].clone();
                    for a in b {
                        *ps[i].entry(a.0).or_insert(0) += a.1;
                    }
                }
            }
            ps
        }

        fn fastpow(x: i32, mut a: i32) -> i32 {
            let mut ans = 1i64;
            let mut p = x as i64;
            while a > 0 {
                if a & 1 > 0 {
                    ans *= p;
                    ans %= 1_000_000_007;
                }
                a >>= 1;
                p *= p as i64;
                p %= 1_000_000_007;
            }
            ans as _
        }
        fn factor() -> (Vec<i32>, Vec<i32>) {
            let size = 10015;
            let mut fac = vec![0; size];
            let mut inv = vec![0; size];
            fac[0] = 1;
            inv[0] = 1;
            let mut num = 1i64;
            for i in 1..fac.len() {
                num = (num * i as i64) % 1_000_000_007;
                fac[i] = num as _;
                inv[i] = fastpow(num as _, 1_000_000_007 - 2);
            }
            (fac, inv)
        }
        let (fac, inv) = factor();
        let pfs = decomposePrimeFactors();
        let mut ans = vec![];
        let mo = 1_000_000_007;
        for q in queries {
            let mut b = 1i64;
            for (_, &a) in &pfs[q[1] as usize] {
                b = fac[a + q[0] as usize - 1] as i64 * inv[q[0] as usize - 1] as i64 % mo * inv[a] as i64 % mo * b % mo;
            }
            ans.push(b as i32);
        }
        ans
    }

}

python3 解法, 执行用时: 336 ms, 内存消耗: 20.6 MB, 提交时间: 2023-10-25 22:51:23

import math


MOD = 10 ** 9 + 7


class Solution:
    
    @staticmethod
    def getPrimes(n):
        primes = []
        for i in range(2, n):
            flag = 0
            for j in range(2, int(i**0.5)+1):
                if (i % j == 0):
                    flag = 1
                    break
            if not flag: primes.append(i)
        return primes
   
    def waysToFillArray(self, queries: List[List[int]]) -> List[int]:
        result = []
        
        primes = self.getPrimes(100)

        for query in queries:
            n, k = query
            ways = 1
            for prime in primes:
                if prime > k:
                    break
                cnt = 0
                while k % prime == 0:
                    # 尝试用 prime 分解 k
                    cnt += 1
                    k /= prime
                ways *= math.comb(n + cnt - 1, cnt)

            if k > 1:
                # 如果最后 k > 1,那么说明 k 无法进一步被分解
                # 此时 k 是一个比较大的质数,比如 2377
                # 只要把 k 放在 n 个格子的任意一个位置,所以有 n 种放法
                ways = ways * n
            result.append(ways % MOD)
        return result

cpp 解法, 执行用时: 60 ms, 内存消耗: 27.7 MB, 提交时间: 2023-10-25 22:49:51

using LL = long long;

class Solution {
private:
    static constexpr int mod = 1000000007;
    static constexpr int nmax = 10000;
    static constexpr int logkmax = 13;
    static int c[nmax + logkmax][logkmax + 1];
    static bool inited;
    
    vector<int> factors;
    int n, k;
    int sum;
    int u;
    
public:
    // 预处理组合数
    void init() {
        if (inited) {
            return;
        }
        inited = true;
        
        c[0][0] = 1;
        for (int i = 1; i < nmax + logkmax; ++i) {
            c[i][0] = 1;
            for (int j = 1; j <= i && j <= logkmax; ++j) {
                c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
                if (c[i][j] >= mod) {
                    c[i][j] -= mod;
                }
            }
        }
    }
    
    vector<int> waysToFillArray(vector<vector<int>>& queries) {
        init();
        
        vector<int> ans;
        for (const auto& q: queries) {
            int n = q[0], k = q[1];
            int sum = 1;
            for (int i = 2; i * i <= k; ++i) {
                if (k % i == 0) {
                    int y = 0;
                    while (k % i == 0) {
                        ++y;
                        k /= i;
                    }
                    sum = (LL)sum * c[n + y - 1][y] % mod;
                }
            }
            if (k != 1) {
                sum = (LL)sum * n % mod;
            }
            ans.push_back(sum);
        }
        return ans;
    }
};

int Solution::c[nmax + logkmax][logkmax + 1] = {0};
bool Solution::inited = false;

cpp 解法, 执行用时: 52 ms, 内存消耗: 31.3 MB, 提交时间: 2023-10-25 22:49:20

constexpr int mod = 1'000'000'007;
constexpr int maxn = 10000 + 13;
int f[maxn], g[maxn];
vector<int> rs[maxn];
int C(int m, int n){
    return 1LL * f[m] * g[n] % mod * g[m - n] % mod;
}
class Solution {
public:
    vector<int> waysToFillArray(vector<vector<int>>& queries) {
        if(f[0] != 1){
            for(int i = 0; i < maxn; i += 1) f[i] = i ? 1LL * f[i - 1] * i % mod : 1;
            for(int i = 1; i < maxn; i += 1) g[i] = i == 1 ? 1 : 1LL * (mod - mod / i) * g[mod % i] % mod;
            for(int i = 0; i < maxn; i += 1) g[i] = g[i] ? 1LL * g[i - 1] * g[i] % mod : 1;
            for(int i = 2; i < maxn; i += 1){
                if(rs[i].empty()){
                    for(int j = i; j < maxn; j += i){
                        rs[j].push_back(0);
                        for(int k = j; k % i == 0; k /= i) rs[j].back() += 1;
                    }
                }
            }
        }
        vector<int> res;
        for(auto v : queries){
            int n = v[0], k = v[1], ans = 1;
            for(int r : rs[k]) ans = 1LL * ans * C(n + r - 1, r) % mod;
            res.push_back(ans);
        }
        return res;
    }
};

cpp 解法, 执行用时: 80 ms, 内存消耗: 29.8 MB, 提交时间: 2023-10-25 22:49:12

constexpr int mod = 1'000'000'007;
int power(int a, int r){
    int res = 1;
    for(; r; r >>= 1, a = 1LL * a * a % mod)
        if(r & 1) res = 1LL * res * a % mod;
    return res;
}
int inv(int n){
    return power(n, mod - 2);
}
int C(int m, int n){
    int res = 1;
    for(int i = 0; i < n; i += 1) res = 1LL * res * (m - i) % mod;
    for(int i = 1; i <= n; i += 1) res = 1LL * res * inv(i) % mod;
    return res;
}

class Solution {
public:
    vector<int> waysToFillArray(vector<vector<int>>& queries) {
        vector<int> res;
        for(auto v : queries){
            int n = v[0], k = v[1], ans = 1;
            for(int i = 2, r; i * i <= k; i += 1)
                if(k % i == 0){
                    for(r = 0; k % i == 0; k /= i) r += 1;
                    ans = 1LL * ans * C(n + r - 1, r) % mod;
                }
            if(k > 1) ans = 1LL * ans * n % mod;
            res.push_back(ans);
        }
        return res;
    }
};

上一题