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)
	


执行结果如下:


左神java代码

以上是关于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] >

在线性时间内查找长度为 N、数字 1 到 N-1 的数组中的重复项,而无需使用额外的 obj/arr 来跟踪计数