3001 Apply Operations To Maximize Score
3001 Apply Operations To Maximize Score
Apply Operations to Maximize Score 
You are given an array nums of n positive integers and an integer k.
Initially, you start with a score of 1. You have to maximize your score by applying the following operation at most k times:
1
2
3
Choose any **non-empty** subarray nums[l, ..., r] that you haven't chosen previously.
Choose an element x of nums[l, ..., r] with the highest **prime score**. If multiple such elements exist, choose the one with the smallest index.
Multiply your score by x.
Here, nums[l, …, r] denotes the subarray of nums starting at index l and ending at the index r, both ends being inclusive.
The prime score of an integer x is equal to the number of distinct prime factors of x. For example, the prime score of 300 is 3 since 300 = 2 * 2 * 3 * 5 * 5.
Return the maximum possible score after applying at most *k operations*.
Since the answer may be large, return it modulo 109 + 7.
Example 1:
1
2
3
4
5
6
7
**Input:** nums = [8,3,9,3,8], k = 2
**Output:** 81
**Explanation:** To get a score of 81, we can apply the following operations:
- Choose subarray nums[2, ..., 2]. nums[2] is the only element in this subarray. Hence, we multiply the score by nums[2]. The score becomes 1 * 9 = 9.
- Choose subarray nums[2, ..., 3]. Both nums[2] and nums[3] have a prime score of 1, but nums[2] has the smaller index. Hence, we multiply the score by nums[2]. The score becomes 9 * 9 = 81.
It can be proven that 81 is the highest score one can obtain.
Example 2:
1
2
3
4
5
6
7
8
9
**Input:** nums = [19,12,14,6,10,18], k = 3
**Output:** 4788
**Explanation:** To get a score of 4788, we can apply the following operations:
- Choose subarray nums[0, ..., 0]. nums[0] is the only element in this subarray. Hence, we multiply the score by nums[0]. The score becomes 1 * 19 = 19.
- Choose subarray nums[5, ..., 5]. nums[5] is the only element in this subarray. Hence, we multiply the score by nums[5]. The score becomes 19 * 18 = 342.
- Choose subarray nums[2, ..., 3]. Both nums[2] and nums[3] have a prime score of 2, but nums[2] has the smaller index. Hence, we multipy the score by nums[2]. The score becomes 342 * 14 = 4788.
It can be proven that 4788 is the highest score one can obtain.
Constraints:
1
2
3
1 <= nums.length == n <= 105
1 <= nums[i] <= 105
1 <= k <= min(n * (n + 1) / 2, 109)
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
class Solution:
MOD = 10**9 + 7
def maximumScore(self, nums, k):
n = len(nums)
prime_scores = [0] * n
# Calculate the prime score for each number in nums
for index in range(n):
num = nums[index]
# Check for prime factors from 2 to sqrt(n)
for factor in range(2, int(math.sqrt(num)) + 1):
if num % factor == 0:
# Increment prime score for each prime factor
prime_scores[index] += 1
# Remove all occurrences of the prime factor from num
while num % factor == 0:
num //= factor
# If num is still greater than or equal to 2, it's a prime factor
if num >= 2:
prime_scores[index] += 1
# Initialize next and previous dominant index arrays
next_dominant = [n] * n
prev_dominant = [-1] * n
# Stack to store indices for monotonic decreasing prime score
decreasing_prime_score_stack = []
# Calculate the next and previous dominant indices for each number
for index in range(n):
# While the stack is not empty and the current prime score is greater than the stack's top
while (
decreasing_prime_score_stack
and prime_scores[decreasing_prime_score_stack[-1]]
< prime_scores[index]
):
top_index = decreasing_prime_score_stack.pop()
# Set the next dominant element for the popped index
next_dominant[top_index] = index
# If the stack is not empty, set the previous dominant element for the current index
if decreasing_prime_score_stack:
prev_dominant[index] = decreasing_prime_score_stack[-1]
# Push the current index onto the stack
decreasing_prime_score_stack.append(index)
# Calculate the number of subarrays in which each element is dominant
num_of_subarrays = [0] * n
for index in range(n):
num_of_subarrays[index] = (next_dominant[index] - index) * (
index - prev_dominant[index]
)
# Priority queue to process elements in decreasing order of their value
processing_queue = []
# Push each number and its index onto the priority queue
for index in range(n):
heapq.heappush(processing_queue, (-nums[index], index))
score = 1
# Helper function to compute the power of a number modulo MOD
def _power(base, exponent):
res = 1
# Calculate the exponentiation using binary exponentiation
while exponent > 0:
# If the exponent is odd, multiply the result by the base
if exponent % 2 == 1:
res = (res * base) % self.MOD
# Square the base and halve the exponent
base = (base * base) % self.MOD
exponent //= 2
return res
# Process elements while there are operations left
while k > 0:
# Get the element with the maximum value from the queue
num, index = heapq.heappop(processing_queue)
num = -num # Negate back to positive
# Calculate the number of operations to apply on the current element
operations = min(k, num_of_subarrays[index])
# Update the score by raising the element to the power of operations
score = (score * _power(num, operations)) % self.MOD
# Reduce the remaining operations count
k -= operations
return score
This post is licensed under CC BY 4.0 by the author.