141 lines
4.8 KiB
C++
141 lines
4.8 KiB
C++
// Source : https://leetcode.com/problems/maximize-number-of-nice-divisors/
|
||
// Author : Hao Chen
|
||
// Date : 2021-03-28
|
||
|
||
/*****************************************************************************************************
|
||
*
|
||
* You are given a positive integer primeFactors. You are asked to construct a positive integer n that
|
||
* satisfies the following conditions:
|
||
*
|
||
* The number of prime factors of n (not necessarily distinct) is at most primeFactors.
|
||
* The number of nice divisors of n is maximized. Note that a divisor of n is nice if it is
|
||
* divisible by every prime factor of n. For example, if n = 12, then its prime factors are [2,2,3],
|
||
* then 6 and 12 are nice divisors, while 3 and 4 are not.
|
||
*
|
||
* Return the number of nice divisors of n. Since that number can be too large, return it modulo 10^9
|
||
* + 7.
|
||
*
|
||
* Note that a prime number is a natural number greater than 1 that is not a product of two smaller
|
||
* natural numbers. The prime factors of a number n is a list of prime numbers such that their product
|
||
* equals n.
|
||
*
|
||
* Example 1:
|
||
*
|
||
* Input: primeFactors = 5
|
||
* Output: 6
|
||
* Explanation: 200 is a valid value of n.
|
||
* It has 5 prime factors: [2,2,2,5,5], and it has 6 nice divisors: [10,20,40,50,100,200].
|
||
* There is not other value of n that has at most 5 prime factors and more nice divisors.
|
||
*
|
||
* Example 2:
|
||
*
|
||
* Input: primeFactors = 8
|
||
* Output: 18
|
||
*
|
||
* Constraints:
|
||
*
|
||
* 1 <= primeFactors <= 10^9
|
||
******************************************************************************************************/
|
||
|
||
/*
|
||
considering `primeFactors = 5`
|
||
|
||
So, we can have the following options:
|
||
1) [2,3,5,7,11] - all of factors are different, then we only can have 1 nice divisor
|
||
2) [2,2,3,5,7] - we can have 2*1*1*1 = 2 nice divisors: 2*3*5*7 and 2*2*3*5*7
|
||
3) [2,2,3,3,5] - we can have 2*2*1 = 4 nice divisors: 2*3*5, 2*2*3*5, 2*3*3*5, 2*2*3*3*5
|
||
4) [2,2,3,3,3] - we can have 2*3 = 6 nice divisors
|
||
5)[2,2,2,2,3] - we can have 4*1 =4 nice divisors: 2*3, 2*2*3, 2*2*2*3, 2*2*2*2*3
|
||
6) [2,2,2,2,2] - we can have 5 nice divisors: 2, 2*2, 2*2*2, 2*2*2*2, 2*2*2*2*2
|
||
|
||
So, we can see we must have some duplicated factors.
|
||
|
||
And what is the best number of duplication ?
|
||
primeFactors = 1, then 1 - example: [2]
|
||
primeFactors = 2, then 2 - example: [2,2]
|
||
primeFactors = 3, then 3 - example: [5,5,5]
|
||
primeFactors = 4, then 4 = 2*2 - example: [2,2,5,5])
|
||
primeFactors = 5, then 5 = 2*3 - example: [3,3,3,5,5])
|
||
primeFactors = 5, then 6 = 3*3 - example: [3,3,3,5,5,5])
|
||
primeFactors = 7, then 3*4 = 12 - example: [3,3,3,5,5,5,5])
|
||
primeFactors = 8, then 3*3*2 = 18 whcih > (2*2*2*2, 2*4*2, 3*5)
|
||
primeFactors = 9, then 3*3*3 = 27
|
||
primeFactors = 10, then 3*3*4 = 36
|
||
|
||
So, we can see the '3' & '4' are specifial,
|
||
- most of case, we can be greedy for `3`
|
||
- but if the final rest is 4, then we need take 4.
|
||
|
||
*/
|
||
|
||
const int mod = 1000000007;
|
||
|
||
class Solution {
|
||
public:
|
||
int maxNiceDivisors(int primeFactors) {
|
||
return maxNiceDivisors_03(primeFactors);
|
||
return maxNiceDivisors_02(primeFactors); //TLE
|
||
return maxNiceDivisors_01(primeFactors); //TLE
|
||
}
|
||
|
||
int maxNiceDivisors_01(int primeFactors) {
|
||
int result = 1;
|
||
while ( primeFactors > 4 ) {
|
||
primeFactors -= 3;
|
||
result = (result * 3l) % mod;
|
||
}
|
||
result = (result * (long)primeFactors) % mod;
|
||
return result;
|
||
}
|
||
|
||
int maxNiceDivisors_02(int primeFactors) {
|
||
if (primeFactors <= 4 ) return primeFactors;
|
||
int result = 1;
|
||
for (int i = 4; i > 0; i-- ){
|
||
if ((primeFactors - i) % 3 == 0){
|
||
result = i;
|
||
primeFactors -= i;
|
||
// now, `primeFactors` is 3 times - 3X
|
||
// we need convert 3X to 3^X
|
||
for (int x = primeFactors/3; x > 0; x-- ) {
|
||
result = (result * 3l) % mod;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
int pow3(int x) {
|
||
long result = 1;
|
||
long factor = 3;
|
||
while(x > 0) {
|
||
if (x & 1) {
|
||
result = (result * factor) % mod;
|
||
|
||
}
|
||
factor *= factor;
|
||
factor %= mod;
|
||
x /= 2;
|
||
}
|
||
return result % mod;
|
||
}
|
||
|
||
int maxNiceDivisors_03(int primeFactors) {
|
||
|
||
if (primeFactors <= 4 ) return primeFactors;
|
||
int result = 1;
|
||
for (int i = 4; i > 0; i-- ){
|
||
if ((primeFactors - i) % 3 == 0){
|
||
primeFactors -= i;
|
||
// now, `primeFactors` is 3 times - 3X
|
||
// we need convert 3X to 3^X
|
||
int x = primeFactors / 3;
|
||
result = (long(i) * pow3(x)) % mod;
|
||
break;
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
};
|