Skip to content

Latest commit

 

History

History

1808.Maximize Number of Nice Divisors

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

给你一个正整数 primeFactors 。你需要构造一个正整数 n ,它满足以下条件:

  • n 质因数(质因数需要考虑重复的情况)的数目 不超过 primeFactors 个。
  • n 好因子的数目最大化。如果 n 的一个因子可以被 n 的每一个质因数整除,我们称这个因子是 好因子 。比方说,如果 n = 12 ,那么它的质因数为 [2,2,3] ,那么 6 和 12 是好因子,但 3 和 4 不是。

请你返回 n 的好因子的数目。由于答案可能会很大,请返回答案对 109 + 7 取余 的结果。

请注意,一个质数的定义是大于 1 ,且不能被分解为两个小于该数的自然数相乘。一个数 n 的质因子是将 n 分解为若干个质因子,且它们的乘积为 n 。

 

示例 1:

输入:primeFactors = 5
输出:6
解释:200 是一个可行的 n 。
它有 5 个质因子:[2,2,2,5,5] ,且有 6 个好因子:[10,20,40,50,100,200] 。
不存在别的 n 有至多 5 个质因子,且同时有更多的好因子。

示例 2:

输入:primeFactors = 8
输出:18

 

提示:

  • 1 <= primeFactors <= 109

解法

方法一:问题转换 + 快速幂

我们可以将 $n$ 进行质因数分解,即 $n = a_1^{k_1} \times a_2^{k_2} \times\cdots \times a_m^{k_m}$,其中 $a_i$ 为质因子,而 $k_i$ 为质因子 $a_i$ 的指数。由于 $n$ 的质因子个数不超过 $primeFactors$ 个,因此 $k_1 + k_2 + \cdots + k_m \leq primeFactors$

而根据题意描述,我们知道 $n$ 的好因子要满足能被所有的质因子整除,也即是说 $n$ 的好因子需要包含 $a_1 \times a_2 \times \cdots \times a_m$ 作为因数。那么好因子的个数 $k= k_1 \times k_2 \times \cdots \times k_m$,即 $k$$k_1, k_2, \cdots, k_m$ 的乘积。要最大化好因子的个数,也即是说我们要将 primeFactors 拆分成 $k_1, k_2, \cdots, k_m$,使得 $k_1 \times k_2 \times \cdots \times k_m$ 最大。因此问题转换为:将整数 primeFactors 拆分成若干个整数的乘积,使得乘积最大。

接下来,我们只需要分情况讨论。

  • 如果 $primeFactors \lt 4$,那么直接返回 primeFactors 即可。
  • 如果 $primeFactors$$3$ 的倍数,那么我们将 primeFactors 拆分成 $3$ 的倍数个 $3$,即 $3^{\frac{primeFactors}{3}}$
  • 如果 $primeFactors$ 除以 $3$$1$,那么我们将 primeFactors 拆分成 $\frac{primeFactors}{3} - 1$$3$,再乘以 $4$,即 $3^{\frac{primeFactors}{3} - 1} \times 4$
  • 如果 $primeFactors$ 除以 $3$$2$,那么我们将 primeFactors 拆分成 $\frac{primeFactors}{3}$$3$,再乘以 $2$,即 $3^{\frac{primeFactors}{3}} \times 2$

以上过程中,我们利用快速幂取模求解。

时间复杂度 $O(\log n)$,空间复杂度 $O(1)$

class Solution:
    def maxNiceDivisors(self, primeFactors: int) -> int:
        mod = 10**9 + 7
        if primeFactors < 4:
            return primeFactors
        if primeFactors % 3 == 0:
            return pow(3, primeFactors // 3, mod) % mod
        if primeFactors % 3 == 1:
            return 4 * pow(3, primeFactors // 3 - 1, mod) % mod
        return 2 * pow(3, primeFactors // 3, mod) % mod
class Solution {
    private final int mod = (int) 1e9 + 7;

    public int maxNiceDivisors(int primeFactors) {
        if (primeFactors < 4) {
            return primeFactors;
        }
        if (primeFactors % 3 == 0) {
            return qpow(3, primeFactors / 3);
        }
        if (primeFactors % 3 == 1) {
            return (int) (4L * qpow(3, primeFactors / 3 - 1) % mod);
        }
        return 2 * qpow(3, primeFactors / 3) % mod;
    }

    private int qpow(long a, long n) {
        long ans = 1;
        for (; n > 0; n >>= 1) {
            if ((n & 1) == 1) {
                ans = ans * a % mod;
            }
            a = a * a % mod;
        }
        return (int) ans;
    }
}
class Solution {
public:
    int maxNiceDivisors(int primeFactors) {
        if (primeFactors < 4) {
            return primeFactors;
        }
        const int mod = 1e9 + 7;
        auto qpow = [&](long long a, long long n) {
            long long ans = 1;
            for (; n; n >>= 1) {
                if (n & 1) {
                    ans = ans * a % mod;
                }
                a = a * a % mod;
            }
            return (int) ans;
        };
        if (primeFactors % 3 == 0) {
            return qpow(3, primeFactors / 3);
        }
        if (primeFactors % 3 == 1) {
            return qpow(3, primeFactors / 3 - 1) * 4L % mod;
        }
        return qpow(3, primeFactors / 3) * 2 % mod;
    }
};
func maxNiceDivisors(primeFactors int) int {
	if primeFactors < 4 {
		return primeFactors
	}
	const mod = 1e9 + 7
	qpow := func(a, n int) int {
		ans := 1
		for ; n > 0; n >>= 1 {
			if n&1 == 1 {
				ans = ans * a % mod
			}
			a = a * a % mod
		}
		return ans
	}
	if primeFactors%3 == 0 {
		return qpow(3, primeFactors/3)
	}
	if primeFactors%3 == 1 {
		return qpow(3, primeFactors/3-1) * 4 % mod
	}
	return qpow(3, primeFactors/3) * 2 % mod
}
/**
 * @param {number} primeFactors
 * @return {number}
 */
var maxNiceDivisors = function (primeFactors) {
    if (primeFactors < 4) {
        return primeFactors;
    }
    const mod = 1e9 + 7;
    const qpow = (a, n) => {
        let ans = 1;
        for (; n; n >>= 1) {
            if (n & 1) {
                ans = Number((BigInt(ans) * BigInt(a)) % BigInt(mod));
            }
            a = Number((BigInt(a) * BigInt(a)) % BigInt(mod));
        }
        return ans;
    };
    const k = Math.floor(primeFactors / 3);
    if (primeFactors % 3 === 0) {
        return qpow(3, k);
    }
    if (primeFactors % 3 === 1) {
        return (4 * qpow(3, k - 1)) % mod;
    }
    return (2 * qpow(3, k)) % mod;
};