-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
maximum-product-after-k-increments.cpp
106 lines (101 loc) · 3.12 KB
/
maximum-product-after-k-increments.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
// Time: O(nlogn)
// Space: O(1)
// math, sort
class Solution {
public:
int maximumProduct(vector<int>& nums, int k) {
static const int MOD = 1e9 + 7;
sort(begin(nums), end(nums));
auto total = accumulate(cbegin(nums), cend(nums), 0ll);
int i = size(nums) - 1;
for (; i >= 0; --i) {
if (nums[i] * static_cast<int64_t>(i + 1) - total <= k) {
break;
}
total -= nums[i];
}
const int q = (k + total) / (i + 1);
const int r = (k + total) % (i + 1);
return ((static_cast<uint64_t>(powmod(q, (i + 1) - r, MOD)) * powmod(q + 1, r, MOD) % MOD) *
accumulate(cbegin(nums) + i + 1, cend(nums), 1ull,
[=](const auto& total, const auto& x) {
return total * x % MOD;
})) % MOD;
}
private:
uint32_t powmod(uint32_t a, uint32_t b, uint32_t mod) {
a %= mod;
uint64_t result = 1;
while (b) {
if (b & 1) {
result = result * a % mod;
}
a = uint64_t(a) * a % mod;
b >>= 1;
}
return result;
}
};
// Time: O(n + k)
// Space: O(n)
// freq table
class Solution2 {
public:
int maximumProduct(vector<int>& nums, int k) {
static const int MOD = 1e9 + 7;
unordered_map<int, int> cnt;
int min_num = numeric_limits<int>::max();
for (const auto& x : nums) {
++cnt[x];
min_num = min(min_num, x);
}
while (k) {
const auto c = min(cnt[min_num], k);
cnt[min_num] -= c;
cnt[min_num + 1] += c;
if (!cnt[min_num]) {
cnt.erase(min_num);
++min_num;
}
k -= c;
}
return accumulate(cbegin(cnt), cend(cnt), 1ull,
[=](const auto& total, const auto& x) {
static const int MOD = 1e9 + 7;
return total * powmod(x.first, x.second, MOD) % MOD;
});
}
private:
uint32_t powmod(uint32_t a, uint32_t b, uint32_t mod) {
a %= mod;
uint64_t result = 1;
while (b) {
if (b & 1) {
result = result * a % mod;
}
a = uint64_t(a) * a % mod;
b >>= 1;
}
return result;
}
};
// Time: O(n + klogn)
// Space: O(1)
// heap
class Solution3 {
public:
int maximumProduct(vector<int>& nums, int k) {
make_heap(begin(nums), end(nums), greater<int>());
while (--k >= 0) {
int x = nums.front();
pop_heap(begin(nums), end(nums), greater<int>()); nums.pop_back();
nums.emplace_back(x + 1);
push_heap(begin(nums), end(nums), greater<int>());
}
return accumulate(cbegin(nums), cend(nums), 1ull,
[](const auto& total, const auto& x) {
static const int MOD = 1e9 + 7;
return total * x % MOD;
});
}
};