Back to all solutions
#2818 - Apply Operations to Maximize Score
Problem 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 109 + 7.
Solution
/**
* @param {number[]} nums
* @param {number} k
* @return {number}
*/
var maximumScore = function(nums, k) {
const MOD = 1000000007n;
const MAX = 100000;
const powerCache = {};
const primeScores = new Array(MAX + 1).fill(0);
for (let prime = 2; prime <= MAX; prime++) {
if (primeScores[prime] > 0) continue;
for (let multiple = prime; multiple <= MAX; multiple += prime) {
primeScores[multiple]++;
}
}
const elements = nums.map(num => [num, primeScores[num], 1]);
const stack = [-1];
const n = elements.length;
for (let i = 0; i <= n; i++) {
while (
stack.length > 1 && (i === n || elements[stack[stack.length - 1]][1] < elements[i][1])
) {
const current = stack.pop();
elements[current][2] = (i - current) * (current - stack[stack.length - 1]);
}
stack.push(i);
}
elements.sort((a, b) => b[0] - a[0]);
let result = 1n;
let remainingOps = k;
for (let i = 0; remainingOps > 0; i++) {
const usedOps = Math.min(remainingOps, elements[i][2]);
remainingOps -= usedOps;
const cacheKey = `${elements[i][0]},${usedOps}`;
let power;
if (cacheKey in powerCache) {
power = powerCache[cacheKey];
} else {
let base = BigInt(elements[i][0]);
let exp = usedOps;
power = 1n;
while (exp > 0) {
if (exp & 1) {
power = (power * base) % MOD;
}
exp >>= 1;
base = (base * base) % MOD;
}
powerCache[cacheKey] = power;
}
result = (result * power) % MOD;
}
return Number(result);
};