2022-05-26:void add(int L, int R, int C)代表在arr[L...R]上每个数加C, int get(int L, int R)代表查询arr[L...R]上的累加
2022-05-26:void add(int L, int R, int C)代表在arr[L…R]上每个数加C,
int get(int L, int R)代表查询arr[L…R]上的累加和,
假设你可以在所有操作开始之前,重新排列arr。
请返回每一次get查询的结果都加在一起最大能是多少。
输入参数:
int[] arr : 原始数组,
int[][] ops,二维数组每一行解释如下:
[a,b,c],如果数组有3个数,表示调用add(a,b,c),
[a,b],如果数组有2个数,表示调用get(a,b),
a和b表示arr范围,范围假设从1开始,不从0开始。
输出:
假设你可以在开始时重新排列arr,返回所有get操作返回值累计和最大是多少?
来自美团。
答案2022-05-26:
线段树。
代码用rust编写。代码如下:
fn main() {
let mut arr: Vec<i32> = vec![1, 2, 3, 4, 5];
let mut ops: Vec<Vec<i32>> = vec![vec![1, 3], vec![2, 4], vec![1, 5]];
println!("ans = {}", max_gets(&mut arr, &mut ops));
}
fn max_gets(arr: &mut Vec<i32>, ops: &mut Vec<Vec<i32>>) -> i32 {
let n = arr.len() as i32;
let mut get_tree = SegmentTree::new(n);
for op in ops.iter_mut() {
if op.len() == 2 {
get_tree.add(op[0], op[1], 1);
}
}
let mut get_cnts: Vec<Vec<i32>> = vec![];
for i in 0..n {
get_cnts.push(vec![]);
for _j in 0..2 {
get_cnts[i as usize].push(0);
}
}
let mut i: i32 = 1;
let mut j: i32 = 0;
while i <= n {
get_cnts[j as usize][0] = j;
get_cnts[j as usize][1] = get_tree.get(i, i);
i += 1;
j += 1;
}
get_cnts.sort_by(|a, b| a[1].cmp(&b[1]));
arr.sort();
let mut re_arrange: Vec<i32> = vec![];
for _i in 0..n {
re_arrange.push(0);
}
for i in 0..n {
re_arrange[get_cnts[i as usize][0] as usize] = arr[i as usize];
}
let mut st = SegmentTree::new2(&mut re_arrange);
let mut ans = 0;
for op in ops.iter_mut() {
if op.len() == 3 {
st.add(op[0], op[1], op[2]);
} else {
ans += st.get(op[0], op[1]);
}
}
return ans;
}
pub struct SegmentTree {
pub n: i32,
pub arr: Vec<i32>,
pub sum: Vec<i32>,
pub lazy: Vec<i32>,
}
impl SegmentTree {
pub fn new(size: i32) -> Self {
let mut n = size + 1;
let mut sum: Vec<i32> = vec![];
let mut lazy: Vec<i32> = vec![];
let arr: Vec<i32> = vec![];
for _i in 0..n << 2 {
sum.push(0);
lazy.push(0);
}
n -= 1;
Self { n, arr, sum, lazy }
}
pub fn new2(origin: &mut Vec<i32>) -> Self {
let mut n = origin.len() as i32 + 1;
let mut arr: Vec<i32> = vec![];
arr.push(0);
for i in 1..n {
arr.push(origin[(i - 1) as usize]);
}
let mut lazy: Vec<i32> = vec![];
let mut sum: Vec<i32> = vec![];
for _i in 0..n << 2 {
sum.push(0);
lazy.push(0);
}
n -= 1;
let mut a = Self { n, arr, sum, lazy };
a.build(1, n, 1);
return a;
}
fn build(&mut self, l: i32, r: i32, rt: i32) {
if l == r {
self.sum[rt as usize] = self.arr[l as usize];
return;
}
let mid = (l + r) >> 1;
self.build(l, mid, rt << 1);
self.build(mid + 1, r, rt << 1 | 1);
self.push_up(rt);
}
fn push_up(&mut self, rt: i32) {
self.sum[rt as usize] = self.sum[(rt << 1) as usize] + self.sum[(rt << 1 | 1) as usize];
}
fn push_down(&mut self, rt: i32, ln: i32, rn: i32) {
if self.lazy[rt as usize] != 0 {
self.lazy[(rt << 1) as usize] += self.lazy[rt as usize];
self.sum[(rt << 1) as usize] += self.lazy[rt as usize] * ln;
self.lazy[(rt << 1 | 1) as usize] += self.lazy[rt as usize];
self.sum[(rt << 1 | 1) as usize] += self.lazy[rt as usize] * rn;
self.lazy[rt as usize] = 0;
}
}
pub fn add(&mut self, ll: i32, rr: i32, cc: i32) {
self.add0(ll, rr, cc, 1, self.n, 1);
}
fn add0(&mut self, ll: i32, rr: i32, cc: i32, l: i32, r: i32, rt: i32) {
if ll <= l && r <= rr {
self.sum[rt as usize] += cc * (r - l + 1);
self.lazy[rt as usize] += cc;
return;
}
let mid = (l + r) >> 1;
self.push_down(rt, mid - l + 1, r - mid);
if ll <= mid {
self.add0(ll, rr, cc, l, mid, rt << 1);
}
if rr > mid {
self.add0(ll, rr, cc, mid + 1, r, rt << 1 | 1);
}
self.push_up(rt);
}
pub fn get(&mut self, ll: i32, rr: i32) -> i32 {
return self.query(ll, rr, 1, self.n, 1);
}
fn query(&mut self, ll: i32, rr: i32, l: i32, r: i32, rt: i32) -> i32 {
if ll <= l && r <= rr {
return self.sum[rt as usize];
}
let mid = (l + r) >> 1;
self.push_down(rt, mid - l + 1, r - mid);
let mut ans = 0;
if ll <= mid {
ans += self.query(ll, rr, l, mid, rt << 1);
}
if rr > mid {
ans += self.query(ll, rr, mid + 1, r, rt << 1 | 1);
}
return ans;
}
}
执行结果如下:

2022-05-26:void add(int L, int R, int C)代表在arr[L...R]上每个数加C, int get(int L, int R)代表查询arr[L...R]上的累加的更多相关文章
- web安全学习笔记(2022/8/26)
网络安全Web学习笔记 @author: lamaper @email: lamaper@qq.com @blog: lamaper - 博客园 (cnblogs.com) @date: Aug.26 ...
- VS Code 调教日记(2022.6.26更新)
VS Code 调教日记(2022.6.26更新) 基于msys2的MinGW-w64 GCC的环境配置 下载并安装msys2 到路径...msys2安装路径...\msys64\etc\pacman ...
- http://www.blogjava.net/zhangchao/archive/2011/05/26/351051.html
http://www.blogjava.net/zhangchao/archive/2011/05/26/351051.html
- 项目Beta冲刺(团队)——05.26(4/7)
项目Beta冲刺(团队)--05.26(4/7) 格式描述 课程名称:软件工程1916|W(福州大学) 作业要求:项目Beta冲刺(团队) 团队名称:为了交项目干杯 作业目标:记录Beta敏捷冲刺第4 ...
- This sample is for changing from “float64” to “int” for values did unmarshal using map[string]interface{}. When it did unmarshal using map[string]interface{}, a number with “int” was changed to “floa
This sample is for changing from “float64” to “int” for values did unmarshal using map[string]interf ...
- .net NPOI Excel导入:时间格式2022/5/26导入变成26-5月-2022
1.问题由来 在做一个导入的需求时,测试导入模板,无论导入模板里的日期设置成何种日期格式到代码中都会提示有不正确的格式化数据,加断点调试发现,导入的日期如:Excel表格中是2022/5/26,断点看 ...
- UPC 2224 Boring Counting (离线线段树,统计区间[l,r]之间大小在[A,B]中的数的个数)
题目链接:http://acm.upc.edu.cn/problem.php?id=2224 题意:给出n个数pi,和m个查询,每个查询给出l,r,a,b,让你求在区间l~r之间的pi的个数(A< ...
- Android打造(ListView、GridView等)通用的下拉刷新、上拉自动加载的组件
原文 http://blog.csdn.net/bboyfeiyu/article/details/39253051 前言 下 拉刷新组件在开发中使用率是非常高的,基本上联网的APP都会采 ...
- ListView下拉刷新,上拉自动加载更多
下拉刷新,Android中非常普遍的功能.为了方便便重写的ListView来实现下拉刷新,同时添加了上拉自动加载更多的功能.设计最初是参考开源中国的Android客户端源码.先看示例图. ...
- luogu P3834 【模板】可持久化线段树 1(主席树) 查询区间 [l, r] 内的第 k 小/大值
————————————————版权声明:本文为CSDN博主「ModestCoder_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明.原文链接:https:// ...
随机推荐
- MySQL基础随笔记
[1]SQL语言入门 我们都知道,数据库管理人员(DBA)通过数据库管理系统(DBMS)可以对数据库(DB)中的数据进行操作,但具体是如何操作的呢?这就涉及到我们本节要讲的SQL语言.SQL ...
- JAVA重试机制多种方式深入浅出
重试机制在分布式系统中,或者调用外部接口中,都是十分重要的. 重试机制可以保护系统减少因网络波动.依赖服务短暂性不可用带来的影响,让系统能更稳定的运行的一种保护机制. 为了方便说明,先假设我们想要进行 ...
- Spring--AOP简介+入门案例
AOP简介 面向切面编程:在不惊动原始设计的基础上,进行功能增强 各个要应用该功能的对象叫做连接点,那个功能叫做通知,表面上的代码没有发生变化,私下里发生变化的连接点,会出现切入点,切入点与通知通过切 ...
- Spring:现代Java开发的必备框架
目录 Spring:现代Java开发的必备框架 Spring创建bean的生命周期以及对应的接口和注解 Spring使用三级缓存解决循环依赖的原理 Spring使用三级缓存创建bean的过程 Spri ...
- Racket while循环
Problem: 1805. 字符串中不同整数的数目 目录 lc题解地址 思路 Code lc题解地址 https://leetcode.cn/problems/number-of-different ...
- Python——基础知识(一)
1. 那么多编程语言,为什么学python 易于学习,是所有编程语言当中最容易学习的 没有最好的语言,只有最合适的语言 2. 反复执行的用例如何提升效率 测试流程回归(回顾) 很多测试用例在不同的测试 ...
- java常用的数据类型有哪些
前言 在上一篇文章中,壹哥给大家讲解了Java中变量的定义.使用及基本原理等内容,这个内容并不是很难,但却是我们走向Java大神的第一步!壹哥希望你从第一天就要认真对待哦. 在前面讲解变量时,壹哥给大 ...
- Java面试——Linux
一.如果知道一个文件名称,怎么查这个文件在 Linux下的哪个目录,如:要查找 tnsnames.ora文件 1 find / -name tnsnames.ora 2 #还可以用locate 来查找 ...
- 迁移学习(PCL)《PCL: Proxy-based Contrastive Learning for Domain Generalization》
论文信息 论文标题:PCL: Proxy-based Contrastive Learning for Domain Generalization论文作者:论文来源:论文地址:download 论文代 ...
- 使用golang+antlr4构建一个自己的语言解析器(完结篇)
Goland 中Antlr4插件 在goland中安装Antlr4插件,用于识别输入的字符在在语法文件中生成的语法树的样子,大概就是如下的摸样 下载步骤: 1.点击文件中的设置选项 2.在插件目录下输 ...