试题 算法训练 操作格子(线段树模板题)
资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
有n个格子,从左到右放成一排,编号为1-n。
共有m次操作,有3种操作类型:
1.修改一个格子的权值,2.求连续一段格子权值和,
3.求连续一段格子的最大值。
对于每个2、3操作输出你所求出的结果。
输入格式
第一行2个整数n,m。接下来一行n个整数表示n个格子的初始权值。
接下来m行,每行3个整数p,x,y,
p表示操作类型,p=1时表示修改格子x的权值为y,p=2时表示求区间[x,y]内格子权值和,p=3时表示求区间[x,y]内格子最大的权值。输出格式
有若干行,行数等于p=2或3的操作总数。每行1个整数,对应了每个p=2或3操作的结果。
样例输入
4 3
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
数据规模与约定
对于20%的数据n <= 100,m<= 200。对于50%的数据n <= 5000,m <= 5000。
对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。
题目链接:操作格子
思路:
从题中可以看出,这是一道区间修改,区间求最大值,区间求和的题,那么我们很快就能想到使用线段树来解决。因为既要存最大值,又要存区间和,那么可以声明一个类/结构体来存储最值以及和。
不熟悉线段树模板的可以见这篇文章:线段树模板
class node{int val, max;
}
代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;public class Main {static int[] arr = new int[100005]; //原数组static node[] tree = new node[arr.length * 5]; //线段树数组public static void main(String[] args) throws IOException {BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String[] nm = reader.readLine().split(" "); //接收n和mint n = Integer.parseInt(nm[0]), m = Integer.parseInt(nm[1]);String[] tmp = reader.readLine().split(" ");//接收数列for(int i = 0; i < n; i++)arr[i] = Integer.parseInt(tmp[i]);for (int i = 0; i < n * 5; i++) {tree[i] = new node();}build(0, 0, n - 1); //建树while(m-- > 0) {String[] order = reader.readLine().split(" ");//判断是哪种操作if (order[0].equals("1")) {update(0, 0, n - 1, Integer.parseInt(order[1]) - 1, Integer.parseInt(order[2]));}else if (order[0].equals("2")) {int sum = sum(0, 0, n - 1, Integer.parseInt(order[1]) - 1, Integer.parseInt(order[2]) - 1);System.out.println(sum);}else if (order[0].equals("3")) {int max = max(0, 0, n - 1, Integer.parseInt(order[1]) - 1, Integer.parseInt(order[2]) - 1);System.out.println(max);}}}//建树public static void build(int k, int l, int r) {if(l == r) {tree[k].val = tree[k].max = arr[l];return;}int mid = (l + r) >> 1;int l_child = 2 * k + 1;int r_child = 2 * k + 2;build(l_child, l, mid);build(r_child, mid + 1, r);tree[k].val = tree[l_child].val + tree[r_child].val;tree[k].max = Math.max(tree[l_child].max, tree[r_child].max);}//更新public static void update(int k, int l, int r, int idx, int val) {if (l == r) {tree[k].val = tree[k].max = val;arr[idx] = val;return;}int mid = (l + r) >> 1;int l_child = 2 * k + 1;int r_child = 2 * k + 2;if (idx <= mid) {update(l_child, l, mid, idx, val);}else {update(r_child, mid + 1, r, idx, val);}tree[k].val = tree[l_child].val + tree[r_child].val;tree[k].max = Math.max(tree[l_child].max, tree[r_child].max);}//求区间和public static int sum(int k, int l, int r, int start, int end) {if(start > r || end < l)return 0;if (start <= l && end >= r)return tree[k].val;int mid = (l + r) >> 1;int l_child = 2 * k + 1;int r_child = 2 * k + 2;int l_sum = sum(l_child, l, mid, start, end);int r_sum = sum(r_child, mid + 1, r, start, end);return l_sum + r_sum;}//求区间最大值public static int max(int k, int l, int r, int start, int end) {if(start > r || end < l)return 0;if (start <= l && end >= r)return tree[k].max;int mid = (l + r) >> 1;int l_child = 2 * k + 1;int r_child = 2 * k + 2;int l_max = max(l_child, l, mid, start, end);int r_max = max(r_child, mid + 1, r, start, end);return Math.max(l_max, r_max);}
}
class node{int val, max;
}
试题 算法训练 操作格子(线段树模板题)相关推荐
- 线段树模板题3:区间染色问题
1.3线段树模板题3:区间染色问题 在DotA游戏中,帕吉的肉钩实际上是大多数英雄中最恐怖的东西.挂钩由长度相同的几个连续的金属棍组成. 现在,帕吉(Pudge)希望对挂接进行一些操作. 让我们将钩子 ...
- J.哭泣的阿木木(线段树模板题)
哭泣的阿木木 Description 没啥用的背景故事: 在远古的恕瑞玛,有一个孤独而又忧郁的灵魂,阿木木.他在世间游荡,只为找到一个朋友.他遭受了一种远古的巫术诅咒,注定忍受永世的孤单,因为被他触碰 ...
- UESTC - 1057 秋实大哥与花 线段树模板题
http://acm.uestc.edu.cn/#/problem/show/1057 题意:给你n个数,q次操作,每次在l,r上加上x并输出此区间的sum 题解:线段树模板, #define _CR ...
- hdu1156(简单线段树 模板题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- 【线段树】[LUOGU 守墓人] [LUOGU 维护序列] 线段树模板题
题目: 题目链接:[LUOGU 守墓人] 题解: 线段树单点修改,区间修改,单点查询,区间查询,一系列线段树基本操作,模板打就好. (回头再补一个分块和树状数组的这种板子题,就是用分块和树状数组再写一 ...
- 蓝桥杯 ALGO-8 算法训练 操作格子(线段树)
问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求 ...
- java实现 蓝桥杯 算法训练 操作格子
问题描述 有n个格子,从左到右放成一排,编号为1-n. 共有m次操作,有3种操作类型: 1.修改一个格子的权值, 2.求连续一段格子权值和, 3.求连续一段格子的最大值. 对于每个2.3操作输出你所求 ...
- 树套树 ---- 树状数组套权值线段树模板题 P2617 Dynamic Rankings 动态第K大
题目链接 题目大意: 给你一个数组aaa,aaa有两个操作 询问aaa中[l,r][l,r][l,r]区间里面第kkk小的数是哪个? 修改axa_xax为yyy 解题思路: 首先我们知道权值线段树是 ...
- poj2823 线段树模板题 点修改(也可以用单调队列)
这道题吧 没计算时间 因为给了那么多 一算还可以 就直接写了线段树,刘汝佳那本模板 然后!poj的g++比C++慢大约500ms.......g++tle,C++就过了 Sliding Window ...
最新文章
- java des zero_android----Java DES加密算法工具类
- linux编辑模式复制快捷键,Linux vim删除、复制、粘贴快捷键
- 模板方法(钩子函数)设计模式
- 内联函数有什么优点?内联函数与宏定义的区别?
- Http Server API路由请求到web程序
- 【HEVC帧间预测论文】P1.2 An Efficient Inter Mode Decision Approach for H.264 Video Codin
- 【Flink】Flink 1.12.2 启动脚本
- 换服务器皮肤文件,lol怎么替换皮肤文件
- 校验非空的注解@NotNull怎么取得自定义的message
- kali linux窗口变大,kali怎么把屏幕放大
- RocketMQ避坑指南:java后端开发电脑配置
- 蛙蛙推荐:蛙蛙教你发明一种新语言之一--词法分析和语法分析
- android intent开启前置摄像头
- Android中播放本地SD卡中歌曲须要的加入的权限
- 计算机网络 与信息安全专业就业,信息安全专业是学什么的 毕业后的就业方向有哪些...
- Linux(二) 常用工具
- ts 打开sourcemap_使用ts-node和vsc来调试TypeScript代码
- 它的出现将统一所有浏览器存储 API ?!
- 不用下载任何软件,比360强力删除还强的删除文件方法
- 23种设计模式——策略模式