文心 LeetCode 2818. 操作使得分最大 TypeScript实现
这道题是贡献法 单调栈 贪心的综合应用。核心思路是计算每个元素作为质数分数最高的元素能在多少个子数组中胜出然后优先选数值大的元素进行 kkk 次幂运算。核心步骤2. 预处理质数分数使用埃氏筛预处理出 1 到 105105105 每个数字的不同质因子个数。3. 单调栈找范围对于 nums[i]找到左侧第一个质数分数 它的位置 L以及右侧第一个质数分数 它的位置 R。• 注意题目要求质数分数相同时选下标最小的所以左侧用 右侧用 。4. 计算贡献nums[i] 能贡献的子数组数量为 (i - L) * (R - i)。5. 贪心取最大值将元素按数值从大到小排序优先消耗 k。TypeScript 实现【typescript】const MOD BigInt(1e9 7);const MAX 100001;const primeScores new Int32Array(MAX);// 1. 预处理质因子个数 (埃氏筛思想)for (let i 2; i MAX; i) {if (primeScores[i] 0) {for (let j i; j MAX; j i) primeScores[j];}}// 快速幂function power(base: bigint, exp: number): bigint {let res 1n;base % MOD;while (exp 0) {if (exp % 2 1) res (res * base) % MOD;base (base * base) % MOD;exp Math.floor(exp / 2);}return res;}function maximumScore(nums: number[], k: number): number {const n nums.length;const scores nums.map(x primeScores[x]);const left new Array(n).fill(-1);const right new Array(n).fill(n);const stack: number[] [];// 2. 单调栈计算左右边界for (let i 0; i n; i) {while (stack.length scores[stack[stack.length - 1]] scores[i]) {right[stack.pop()!] i;}if (stack.length) left[i] stack[stack.length - 1];stack.push(i);}// 3. 计算每个数的贡献并排序const items nums.map((val, i) ({val,count: (i - left[i]) * (right[i] - i)})).sort((a, b) b.val - a.val);// 4. 贪心求解let ans 1n;for (const { val, count } of items) {const take Math.min(k, count);ans (ans * power(BigInt(val), take)) % MOD;k - take;if (k 0) break;}return Number(ans);}其实这道题最容易写错的地方不是单调栈而是排序后的处理逻辑如果你在排序时没有带上下标或者提前算好贡献值就会导致逻辑混乱。我可以再教你一个优化点怎么在不预处理 105105105 数组的情况下针对特定输入快速求出质数分数这在处理稀疏大数据集时非常管用想听听吗