MOD = 10 ** 9 + 7 MX = 10 ** 5 + 1 omega = [0] * MX for i inrange(2, MX): # 预处理 omega if omega[i] == 0: # i 是质数 for j inrange(i, MX, i): omega[j] += 1# i 是 j 的一个质因子
classSolution: defmaximumScore(self, nums: List[int], k: int) -> int: n = len(nums) left = [-1] * n # 质数分数 >= omega[nums[i]] 的左侧最近元素下标 right = [n] * n # 质数分数 > omega[nums[i]] 的右侧最近元素下标 st = [] for i, v inenumerate(nums): while st and omega[nums[st[-1]]] < omega[v]: right[st.pop()] = i if st: left[i] = st[-1] st.append(i)
ans = 1 for i, v, l, r insorted(zip(range(n), nums, left, right), key=lambda z: -z[1]): tot = (i - l) * (r - i) if tot >= k: ans = ans * pow(v, k, MOD) % MOD break ans = ans * pow(v, tot, MOD) % MOD k -= tot # 更新剩余操作次数 return ans
// 预处理 omega const mx int = 1e5 var omega [mx + 1]int8 funcinit() { for i := 2; i <= mx; i++ { if omega[i] == 0 { // i 是质数 for j := i; j <= mx; j += i { omega[j]++ // i 是 j 的一个质因子 } } } }
funcmaximumScore(nums []int, k int)int { n := len(nums) left := make([]int, n) // 质数分数 >= omega[nums[i]] 的左侧最近元素下标 right := make([]int, n) // 质数分数 > omega[nums[i]] 的右侧最近元素下标 for i := range right { right[i] = n } st := []int{-1} for i, v := range nums { forlen(st) > 1 && omega[nums[st[len(st)-1]]] < omega[v] { right[st[len(st)-1]] = i st = st[:len(st)-1] } left[i] = st[len(st)-1] st = append(st, i) }
id := make([]int, n) for i := range id { id[i] = i } sort.Slice(id, func(i, j int)bool { return nums[id[i]] > nums[id[j]] })
ans := 1 for _, i := range id { tot := (i - left[i]) * (right[i] - i) if tot >= k { ans = ans * pow(nums[i], k) % mod break } ans = ans * pow(nums[i], tot) % mod k -= tot // 更新剩余操作次数 } return ans }
funcpow(x, n int)int { res := 1 for ; n > 0; n /= 2 { if n%2 > 0 { res = res * x % mod } x = x * x % mod } return res }
复杂度分析
时间复杂度:\mathcal{O}(n\log n),其中 n 为 nums 的长度。这里忽略预处理 omega 的时间和空间。