Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# [2818.Apply Operations to Maximize Score][title]

## Description

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:

- 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 `10^9 + 7`.

**Example 1:**

```
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:**

```
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.
```

## 结语

如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm][me]

[title]: https://leetcode.com/problems/apply-operations-to-maximize-score/
[me]: https://github.com/kylesliu/awesome-golang-algorithm
Original file line number Diff line number Diff line change
@@ -1,5 +1,141 @@
package Solution

func Solution(x bool) bool {
import (
"container/heap"
)

const mod2818 = 1_000_000_007

type Pair2818 struct {
value int
index int
}

// PriorityQueue implements a priority queue for pairs based on value
type PriorityQueue []Pair2818

func (pq PriorityQueue) Len() int {
return len(pq)
}

func (pq PriorityQueue) Less(i, j int) bool {
return pq[i].value > pq[j].value // Max-heap based on value
}

func (pq PriorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueue) Push(x interface{}) {
*pq = append(*pq, x.(Pair2818))
}

func (pq *PriorityQueue) Pop() interface{} {
old := *pq
n := len(old)
x := old[n-1]
*pq = old[0 : n-1]
return x
}

// Helper function to compute the number of distinct prime factors
func distinctPrimeFactors(x int) int {
count := 0
for i := 2; i*i <= x; i++ {
if x%i == 0 {
count++
for x%i == 0 {
x /= i
}
}
}
if x > 1 {
count++ // If x is a prime number larger than sqrt(original x)
}
return count
}

func Solution(nums []int, k int) int {
n := len(nums)
primeScores := make([]int, n)

for i := 0; i < n; i++ {
primeScores[i] = distinctPrimeFactors(nums[i])
}

nextDominant := make([]int, n)
prevDominant := make([]int, n)
for i := 0; i < n; i++ {
nextDominant[i] = n
prevDominant[i] = -1
}

stack := []int{}

for i := 0; i < n; i++ {
for len(stack) > 0 && primeScores[stack[len(stack)-1]] < primeScores[i] {
topIndex := stack[len(stack)-1]
stack = stack[:len(stack)-1]
nextDominant[topIndex] = i
}

if len(stack) > 0 {
prevDominant[i] = stack[len(stack)-1]
}

stack = append(stack, i)
}

numOfSubarrays := make([]int64, n)
for i := 0; i < n; i++ {
numOfSubarrays[i] = int64(nextDominant[i]-i) * int64(i-prevDominant[i])
}

pq := &PriorityQueue{}
heap.Init(pq)

// Push each number and its index onto the priority queue
for i := 0; i < n; i++ {
heap.Push(pq, Pair2818{value: nums[i], index: i})
}

score := int64(1)

// Process elements while there are operations left
for k > 0 {
// Get the element with the maximum value from the queue
top := heap.Pop(pq).(Pair2818)
num := top.value
index := top.index

// Calculate operations to apply on the current element
operations := int64(k)
if operations > numOfSubarrays[index] {
operations = numOfSubarrays[index]
}

// Update the score
score = (score * power(num, operations)) % mod2818

// Reduce the remaining operations count
k -= int(operations)
}

return int(score)
}

// Helper function to compute the power of a number modulo mod2818
func power(base int, exponent int64) int64 {
res := int64(1)

// Calculate the exponentiation using binary exponentiation
for exponent > 0 {
if exponent%2 == 1 {
res = (res * int64(base)) % mod2818
}
base = (base * base) % mod2818
exponent /= 2
}

return res
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,30 +10,30 @@ func TestSolution(t *testing.T) {
// 测试用例
cases := []struct {
name string
inputs bool
expect bool
nums []int
k int
expect int
}{
{"TestCase", true, true},
{"TestCase", true, true},
{"TestCase", false, false},
{"TestCase1", []int{8, 3, 9, 3, 8}, 2, 81},
{"TestCase2", []int{19, 12, 14, 6, 10, 18}, 3, 4788},
}

// 开始测试
for i, c := range cases {
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
got := Solution(c.inputs)
got := Solution(c.nums, c.k)
if !reflect.DeepEqual(got, c.expect) {
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
c.expect, got, c.inputs)
t.Fatalf("expected: %v, but got: %v, with inputs: %v %v",
c.expect, got, c.nums, c.k)
}
})
}
}

// 压力测试
// 压力测试
func BenchmarkSolution(b *testing.B) {
}

// 使用案列
// 使用案列
func ExampleSolution() {
}
Loading