-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
MaximizeNumberOfNiceDivisors.cpp
140 lines (125 loc) · 4.85 KB
/
MaximizeNumberOfNiceDivisors.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 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;
}
};