2022-03-18:arr数组长度为n, magic数组长度为m 比如 arr = { 3, 1, 4, 5, 7 },如果完全不改变arr中的值, 那么收益就是累加和 = 3 + 1 + 4 +
Posted 福大大架构师每日一题
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2022-03-18:arr数组长度为n, magic数组长度为m 比如 arr = { 3, 1, 4, 5, 7 },如果完全不改变arr中的值, 那么收益就是累加和 = 3 + 1 + 4 +相关的知识,希望对你有一定的参考价值。
2022-03-18:arr数组长度为n, magic数组长度为m
比如 arr = 3, 1, 4, 5, 7 ,如果完全不改变arr中的值,
那么收益就是累加和 = 3 + 1 + 4 + 5 + 7 = 20
magics[i] = a,b,c 表示arr[a~b]中的任何一个值都能改成c
并且每一种操作,都可以执行任意次,其中 0 <= a <= b < n
那么经过若干次的魔法操作,你当然可能得到arr的更大的累加和
返回arr尽可能大的累加和
n <= 10^7 m <= 10^6 arr中的值和c的范围 <= 10^12
答案2022-03-18:
线段树。
代码用golang编写。代码如下:
package main
import (
"fmt"
"sort"
)
func main()
arr := []int3, 1, 4, 5, 7
magics := [][]int2, 5, 5, 1, 3, 2
ret := maxSum3(arr, magics)
fmt.Println(ret)
// O(N) + O(M * logM) + O(M * logN) + O(N)
func maxSum3(arr []int, magics [][]int) int
n := len(arr)
st := NewSegmentTree3(n)
sort.Slice(magics, func(i, j int) bool
a := magics[i]
b := magics[j]
return a[2] < b[2]
)
for _, magic := range magics
st.update0(magic[0]+1, magic[1]+1, magic[2], 1, n, 1)
ans := 0
query := st.buildSingleQuery(n)
for i := 0; i < n; i++
ans += getMax(query[i], arr[i])
return ans
// 为方法三特别定制的线段树
// 区间上维持最大值的线段树
// 支持区间值更新
// 为本道题定制了一个方法:
// 假设全是单点查询,请统一返回所有单点的结果(一个结果数组,里面有所有单点记录)
type SegmentTree3 struct
max []int
change []int
update []bool
index int
func NewSegmentTree3(size int) *SegmentTree3
ans := &SegmentTree3
N := size + 1
ans.max = make([]int, N<<2)
ans.change = make([]int, N<<2)
ans.update = make([]bool, N<<2)
return ans
func (this *SegmentTree3) pushUp(rt int)
this.max[rt] = getMax(this.max[rt<<1], this.max[rt<<1|1])
func getMax(a, b int) int
if a > b
return a
else
return b
func (this *SegmentTree3) pushDown(rt, ln, rn int)
if this.update[rt]
this.update[rt<<1] = true
this.update[rt<<1|1] = true
this.change[rt<<1] = this.change[rt]
this.change[rt<<1|1] = this.change[rt]
this.max[rt<<1] = this.change[rt]
this.max[rt<<1|1] = this.change[rt]
this.update[rt] = false
func (this *SegmentTree3) update0(L, R, C, l, r, rt int)
if L <= l && r <= R
this.update[rt] = true
this.change[rt] = C
this.max[rt] = C
return
mid := (l + r) >> 1
this.pushDown(rt, mid-l+1, r-mid)
if L <= mid
this.update0(L, R, C, l, mid, rt<<1)
if R > mid
this.update0(L, R, C, mid+1, r, rt<<1|1)
this.pushUp(rt)
func (this *SegmentTree3) buildSingleQuery(n int) []int
ans := make([]int, n+1)
this.process(ans, 1, n, 1)
return ans
func (this *SegmentTree3) process(ans []int, l, r, rt int)
if l == r
ans[this.index] = this.max[rt]
this.index++
else
mid := (l + r) >> 1
this.pushDown(rt, mid-l+1, r-mid)
this.process(ans, l, mid, rt<<1)
this.process(ans, mid+1, r, rt<<1|1)
执行结果如下:
以上是关于2022-03-18:arr数组长度为n, magic数组长度为m 比如 arr = { 3, 1, 4, 5, 7 },如果完全不改变arr中的值, 那么收益就是累加和 = 3 + 1 + 4 +的主要内容,如果未能解决你的问题,请参考以下文章
2023-01-06:给定一个只由小写字母组成的字符串str,长度为N, 给定一个只由01组成的数组arr,长度为N, arr[i] == 0表示str中i位置的字符不许修改, arr[i] ==
2022-08-22:给定一个数组arr,长度为n,最多可以删除一个连续子数组, 求剩下的数组,严格连续递增的子数组最大长度。 n <= 10^6。 来自字节。5.6笔试。
2022-08-06:给定一个数组arr,长度为N,arr中所有的值都在1~K范围上, 你可以删除数字,目的是让arr的最长递增子序列长度小于K。 返回至少删除几个数字能达到目的。 N <= 10^4
2022-01-12:给定一个正数数组arr,长度为n,下标0~n-1, arr中的0n-1位置不需要达标,它们分别是最左最右的位置, 中间位置i需要达标,达标的条件是 : arr[i-1] >