您的位置:首页 > 健康 > 美食 > Leetcode3165. 不包含相邻元素的子序列的最大和(Go中的线段树分治包含多类数据使用maintain进行维护)

Leetcode3165. 不包含相邻元素的子序列的最大和(Go中的线段树分治包含多类数据使用maintain进行维护)

2024/7/6 19:18:40 来源:https://blog.csdn.net/weixin_40986490/article/details/139287484  浏览:    关键词:Leetcode3165. 不包含相邻元素的子序列的最大和(Go中的线段树分治包含多类数据使用maintain进行维护)

题目截图

在这里插入图片描述

题目分析

不能取相邻的,就是打家劫舍
然后更改某一个值就是单点更新
更新后,需要更新区间的值
需要注意的是,使用分治时需要考虑到一头一尾的问题,所以有4种情况(选or不选在两个位置)
这四种情况需要在maintain中维护

ac code

// f00 表示第一个数一定不选,最后一个数一定不选
// f01 表示第一个数一定不选,最后一个数可选可不选
// f10 表示第一个数可选可不选,最后一个数一定不选
// f11 表示第一个数可选可不选,最后一个数可选可不选,也就是没有任何限制
// 答案是根节点的f11,没有任何限制
// 按照分治的思想结合线段树处理
// 线段树包含以上四个f进行maintain
type data struct {f00, f01, f10, f11 int}
type seg []data func(t seg) maintain(o int) {// 左右孩子a, b := t[o<<1], t[o<<1|1]t[o] = data {max(a.f00 + b.f10, a.f01 + b.f00),max(a.f00 + b.f11, a.f01 + b.f01),max(a.f10 + b.f10, a.f11 + b.f00),max(a.f10 + b.f11, a.f11 + b.f01),}
}func(t seg) build (a []int, o, l, r int) {if l == r {// 边界只需考虑f11,其他都不能取t[o].f11 = max(a[l], 0)return}m := (l + r) >> 1t.build(a, o<<1, l, m)t.build(a, o<<1|1, m + 1, r)t.maintain(o)
}// 单点更新
func(t seg) update(o, l, r, i, val int) {if l == r {// 边界只需考虑f11,其他都不能取t[o].f11 = max(val, 0)return}m := (l + r) >> 1if i <= m {t.update(o<<1, l, m, i, val)} else {t.update(o<<1|1, m + 1, r, i, val)}t.maintain(o)
}func maximumSumSubsequence(nums []int, queries [][]int) (ans int) {n := len(nums)t := make(seg, 2<<bits.Len(uint(n)))t.build(nums, 1, 0, n - 1)for _, q := range queries {t.update(1, 0, n - 1, q[0], q[1])ans += t[1].f11 // f11是整个数组的没有限制}return ans % 1_000_000_007
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com