2021-11-27:给定一个数组arr,长度为N,做出一个结构,可以高效的做如下的查询: 1) int querySum(L,R) : 查询arr[L...R]上的累加和; 2) int query
2021-11-27:给定一个数组arr,长度为N,做出一个结构,可以高效的做如下的查询:
- int querySum(L,R) : 查询arr[L…R]上的累加和;
- int queryAim(L,R) : 查询arr[L…R]上的目标值,目标值定义如下:
 假设arr[L…R]上的值为[a,b,c,d],a+b+c+d = s,
 目标值为 : (s-a)^2 + (s-b)^2 + (s-c)^2 + (s-d)^2;
- int queryMax(L,R) : 查询arr[L…R]上的最大值.
 要求:
- 初始化该结构的时间复杂度不能超过O(N*logN);
- 三个查询的时间复杂度不能超过O(logN);
- 查询时,认为arr的下标从1开始,比如 :
 arr = [ 1, 1, 2, 3 ];
 querySum(1, 3) -> 4;
 queryAim(2, 4) -> 50;
 queryMax(1, 4) -> 3。
 来自美团。
答案2021-11-27:
querySum方法,前缀和。
 queryAim方法,前缀和,平方数组的前缀和,线段树。对目标值展开,(N-2)*S平方+a1的平方+a2的平方+…+an的平方。
 queryMax方法,线段树。
代码用golang编写。代码如下:
package main
import (
    "fmt"
    "math"
)
func main() {
    q := NewQuery([]int{1, 2, 3, 4, 5})
    ret := 0
    ret = q.querySum(1, 3)
    fmt.Println(ret)
    ret = q.queryAim(1, 3)
    fmt.Println(ret)
    ret = q.queryMax(1, 3)
    fmt.Println(ret)
}
type SegmentTree struct {
    max    []int
    change []int
    update []bool
}
func NewSegmentTree(N int) *SegmentTree {
    ret := &SegmentTree{}
    ret.max = make([]int, N<<2)
    ret.change = make([]int, N<<2)
    ret.update = make([]bool, N<<2)
    for i := 0; i < len(ret.max); i++ {
        ret.max[i] = math.MinInt64
        return ret
    }
    return ret
}
func (this *SegmentTree) pushUp(rt int) {
    this.max[rt] = getMax(this.max[rt<<1], this.max[rt<<1|1])
}
func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}
// ln表示左子树元素结点个数,rn表示右子树结点个数
func (this *SegmentTree) 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 *SegmentTree) 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 *SegmentTree) query(L, R, l, r, rt int) int {
    if L <= l && r <= R {
        return this.max[rt]
    }
    mid := (l + r) >> 1
    this.pushDown(rt, mid-l+1, r-mid)
    left := 0
    right := 0
    if L <= mid {
        left = this.query(L, R, l, mid, rt<<1)
    }
    if R > mid {
        right = this.query(L, R, mid+1, r, rt<<1|1)
    }
    return getMax(left, right)
}
type Query struct {
    sum1 []int
    sum2 []int
    st   *SegmentTree
    m    int
}
func NewQuery(arr []int) *Query {
    ret := &Query{}
    n := len(arr)
    ret.m = len(arr) + 1
    ret.sum1 = make([]int, ret.m)
    ret.sum2 = make([]int, ret.m)
    ret.st = NewSegmentTree(ret.m)
    for i := 0; i < n; i++ {
        ret.sum1[i+1] = ret.sum1[i] + arr[i]
        ret.sum2[i+1] = ret.sum2[i] + arr[i]*arr[i]
        ret.st.update0(i+1, i+1, arr[i], 1, ret.m, 1)
    }
    return ret
}
func (this *Query) querySum(L, R int) int {
    return this.sum1[R] - this.sum1[L-1]
}
func (this *Query) queryAim(L, R int) int {
    sumPower2 := this.querySum(L, R)
    sumPower2 *= sumPower2
    return this.sum2[R] - this.sum2[L-1] + (R-L-1)*sumPower2
}
func (this *Query) queryMax(L, R int) int {
    return this.st.query(L, R, 1, this.m, 1)
}
执行结果如下:
 
2021-11-27:给定一个数组arr,长度为N,做出一个结构,可以高效的做如下的查询: 1) int querySum(L,R) : 查询arr[L...R]上的累加和; 2) int query的更多相关文章
- delphi 判断一个数组的长度用 Length 还是 SizeOf ?
		判断一个数组的长度用 Length 还是 SizeOf ?最近发现一些代码, 甚至有一些专家代码, 在遍历数组时所用的数组长度竟然是 SizeOf(arr); 这不合适! 如果是一维数组.且元素大小是 ... 
- 判断一个数组的长度用 Length 还是 SizeOf ?
		最近发现一些代码, 甚至有一些专家代码, 在遍历数组时所用的数组长度竟然是 SizeOf(arr); 这不合适! 如果是一维数组.且元素大小是一个字节, 这样用看不出错误, 譬如: var arr ... 
- java 一个数组的长度
		package java03; /* *如何获取数组长度 : * 格式: * 数组名称.length * * 这会得到一个int数字,代表数组的长度 * * 数组一旦创建,程序运行期间,长度不可改变 ... 
- Solution -「2021.11.27」\Infty
		T1. 显然往 \(x < 0, y < 0\) 的点走一定不优. 根据转移式可发现 \(C(x, y)\) 即从 \((0, 0)\) 走到 \((x, y)\) 的方案数 \(\dbi ... 
- smarty中判断一个变量是否存在于一个数组中或是否存在于一个字符串中?
		smarty支持php的系统函数可以直接使用{if in_array($str, $arr) || strpos($str, $string)} yes {else} no{/if} 
- Java  高效检查一个数组中是否包含某个值
		如何检查一个数组(未排序)中是否包含某个特定的值?在Java中,这是一个非常有用并又很常用的操作.同时,在StackOverflow中,有时一个得票非常高的问题.在得票比较高的几个回答中,时间复杂度差 ... 
- splice() 方法通过删除现有元素和/或添加新元素来更改一个数组的内容。
		var myFish = ["angel", "clown", "mandarin", "surgeon"]; //从第 ... 
- 包含MIN函数的栈+一个数组实现两个堆栈+两个数组实现MIN栈
		1.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 思路:利用一个辅助栈来存放最小值 栈 3,4,2,5,1 辅助栈 3,2,1 每入栈一次,就与辅 ... 
- 华为机试001:字符串最后一个单词的长度(华为OJ001)
		华为机试 字符串最后一个单词的长度 计算字符串最后一个单词的长度,单词以空格隔开. 提交网址: http://www.nowcoder.com/practice/8c949ea5f36f422594b ... 
- 【es6】将2个数组合并为一个数组
		//第一种 一个数组中的值为key 一个数组中的值为value let arr1 = ['内存','颜色','尺寸']; let arr2 = [1,2,3]; let temp = arr1.map ... 
随机推荐
- .net core 使用 Nlog 配置文件
			nlog.config文件 安装nuget包: NLog.Web.AspNetCore 配置开始 <?xml version="1.0" encoding="utf ... 
- Git 小技巧:忽略某些文件的更改
			*以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/dp9Mwq7vf0ASF_FftBN8Ww 作为一枚合格的代码贡献 ... 
- 面向对象分析与设计(V3)第一章:复杂性
			书名(中):面向对象分析与设计 书名(英):Object-Oriented Analysis and Design with Applications 作者:Grady Booch等 第一部分.概念 ... 
- 20个值得收藏的实用JavaScript技巧
			1.确定对象的数据类型 function myType(type) { return Object.prototype.toString.call(type).slice(8, -1); 使用Obje ... 
- 【LeetCode贪心#12】图解监控二叉树(正宗hard题,涉及贪心分析、二叉树遍历以及状态转移)
			监控二叉树 力扣题目链接(opens new window) 给定一个二叉树,我们在树的节点上安装摄像头. 节点上的每个摄影头都可以监视其父对象.自身及其直接子对象. 计算监控树的所有节点所需的最小摄 ... 
- flutter issue---->Scaffold.of(context)
			当我们想showSnackBar的时候,需要通过Scaffold.of(context)得到Scaffold.但是如果这个context用错的话,flutter就会抛出错误.下面我们通过代码仔细看一下 ... 
- Rainbond的 Gateway API 插件制作实践
			Gateway API 作为新一代的流量管理标准,对原有 Ingress 的扩展不规范.移植性差等问题做出了改进.从兼容K8s生态和优化网关体验出发,Rainbond 支持以插件的形式扩展平台网关能力 ... 
- 构建基于深度学习神经网络协同过滤模型(NCF)的视频推荐系统(Python3.10/Tensorflow2.11)
			毋庸讳言,和传统架构(BS开发/CS开发)相比,人工智能技术确实有一定的基础门槛,它注定不是大众化,普适化的东西.但也不能否认,人工智能技术也具备像传统架构一样"套路化"的流程,也 ... 
- Redis系列12:Redis 的事务机制
			Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ... 
- 强大的 apt-get 命令
			强大的 apt-get 命令(小结) 一.ubuntu下管理软件最方便的非 apt-get 工具莫属了,它的常见用法稍微整理一下供以后参考(详细见 man apt-get ): 1.更新源,升级软件和 ... 
