java实现 蓝桥杯 算法训练 操作格子
问题描述
有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。
运行超时,一半的分数,还望java大佬解决
package com.liuzhen.systemExe;
import java.util.Scanner;
public class Main{
public int[][] segTree;
/*
* 参数root:代表线段树的根节点,此处使用数组存放线段树,其根节点从0开始计数,那么其两个子节点编号必定满足2*root+1或者2*root+2
* 参数array:给定的目标数组,需要转成相应功能的线段树
* 参数start:线段树划分给定数组区间的起始位置
* 参数end:线段树划分给定数组区间的末尾位置
* 函数功能:返回一个线段树,其所有节点均存放当前数组子区间内的总和以及最大值
*/
public void buildSegTree(int root, int[] array, int start, int end) {
if(start == end) {
segTree[root][0] = array[start];
segTree[root][1] = array[start];
} else {
int mid = (start + end) / 2;
buildSegTree(2 * root + 1, array, start, mid); //递归构造左半子树
buildSegTree(2 * root + 2, array, mid + 1, end); //递归构造右半子树
segTree[root][0] = (segTree[2*root+1][0] > segTree[2*root+2][0] ?
segTree[2*root+1][0] : segTree[2*root+2][0]); //回溯求取当前节点区间存放的元素最大值
segTree[root][1] = segTree[root*2+1][1] + segTree[root*2+2][1]; //回溯求取当前节点区间存放的元素总和
}
}
/*
* 参数root:开始进行查找的根节点对应的数组下标值
* 参数start-end:当前节点所表示的区间
* 参数qstart-qend:此次查询的区间
* 函数功能:查询当前区间qstart-qend的最大值
*/
public int querySegTreeMax(int root, int start, int end, int qstart, int qend) {
if(qstart > end || qend < start)
return 0;
int max = 0;
if(qstart <= start && qend >= end) {
return segTree[root][0];
} else {
int mid = (start + end) / 2;
int temp1 = querySegTreeMax(root * 2 + 1, start, mid, qstart, qend);
int temp2 = querySegTreeMax(root * 2 + 2, mid + 1, end, qstart, qend);
if(temp1 > temp2)
max = temp1;
else
max = temp2;
}
return max;
}
/*
* 参数root:开始进行查找的根节点对应的数组下标值
* 参数start-end:当前节点所表示的区间
* 参数qstart-qend:此次查询的区间
* 函数功能:查询当前区间qstart-qend的总和
*/
public int querySegTreeSum(int root, int start, int end, int qstart, int qend) {
if(qstart > end || qend < start )
return 0;
int sum = 0;
if(qstart == start && qend == end) {
return segTree[root][1];
} else {
int mid = (start + end) / 2;
if(qstart <= mid && qend > mid) {
int temp1 = querySegTreeSum(root * 2 + 1, start, mid, qstart, mid);
int temp2 = querySegTreeSum(root * 2 + 2, mid + 1, end, mid + 1, qend);
sum = temp1 + temp2;
} else if(qstart > mid) {
int temp2 = querySegTreeSum(root * 2 + 2, mid + 1, end, qstart, qend);
sum = temp2;
} else if(qend <= mid) {
int temp1 = querySegTreeSum(root * 2 + 1, start, mid, qstart, qend);
sum = temp1;
}
}
return sum;
}
/*
* 参数root:开始进行查找的根节点对应的数组下标值
* 参数qstart-qend:当前节点所表示的区间
* 函数功能:把数组下标为index的元素值变成value,并更新线段树
*/
public void updateSegTree(int root, int qstart, int qend, int index, int value) {
if(qstart == qend) {
if(index == qstart) {
segTree[root][0] = value;
segTree[root][1] = value;
}
return;
}
int mid = (qstart + qend) / 2;
if(mid >= index) {
updateSegTree(root * 2 + 1, qstart, mid, index, value);
} else {
updateSegTree(root * 2 + 2, mid + 1, qend, index, value);
}
//回溯更新改变值元素值的根节点相应值
segTree[root][0] = (segTree[root*2+1][0] > segTree[root*2+2][0] ?
segTree[root*2+1][0] : segTree[root*2+2][0]);
segTree[root][1] = segTree[root*2+1][1] + segTree[root*2+2][1];
}
public void printResult(int[] A, int[][] operation) {
segTree = new int[4 * A.length][2];//此处初始化线段树行的长度为4 * n,有n个元素的数组构造的线段树其对应的二叉树层数最大可以达到4*n个节点
buildSegTree(0, A, 0, A.length - 1);
for(int i = 0;i < operation.length;i++) {
if(operation[i][0] == 1) {
updateSegTree(0, 0, A.length - 1, operation[i][1] - 1, operation[i][2]);
} else if(operation[i][0] == 2) {
int sum = querySegTreeSum(0, 0, A.length - 1, operation[i][1] - 1, operation[i][2] - 1);
System.out.println(sum);
} else if(operation[i][0] == 3) {
int max = querySegTreeMax(0, 0, A.length - 1, operation[i][1] - 1, operation[i][2] - 1);
System.out.println(max);
}
}
}
public static void main(String[] args){
Main test = new Main();
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
if(n >100000 || n <= 0 || m > 100000 || m <= 0) //此处是依据题意给定范围做判断
return;
int[] A = new int[n];
for(int i = 0;i < n;i++)
A[i] = in.nextInt();
int[][] operation = new int[m][3];
for(int i = 0;i < m;i++) {
for(int j = 0;j < 3;j++) {
operation[i][j] = in.nextInt();
}
}
test.printResult(A, operation);
}
}
java实现 蓝桥杯 算法训练 操作格子的更多相关文章
- Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...
- Java实现蓝桥杯 算法训练 大等于n的最小完全平方数
试题 算法训练 大等于n的最小完全平方数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输出大等于n的最小的完全平方数. 若一个数能表示成某个自然数的平方的形式,则称这个数为完全平 ...
- Java实现 蓝桥杯 算法训练 Beaver's Calculator
试题 算法训练 Beaver's Calculator 问题描述 从万能词典来的聪明的海狸已经使我们惊讶了一次.他开发了一种新的计算器,他将此命名为"Beaver's Calculator ...
- Java实现 蓝桥杯 算法训练 Lift and Throw
试题 算法训练 Lift and Throw 问题描述 给定一条标有整点(1, 2, 3, -)的射线. 定义两个点之间的距离为其下标之差的绝对值. Laharl, Etna, Flonne一开始在这 ...
- Java实现 蓝桥杯 算法训练 Remember the A La Mode(暴力)
试题 算法训练 Remember the A La Mode 问题描述 Hugh Samston经营着一个为今年的ICPC世界总决赛的参与者提供甜点的餐饮服务.他将会提供上面有冰激凌的饼片.为了满足不 ...
- Java实现 蓝桥杯 算法训练 删除数组零元素
算法训练 删除数组零元素 时间限制:1.0s 内存限制:512.0MB 提交此题 从键盘读入n个整数放入数组中,编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移 ...
- Java实现 蓝桥杯 算法训练 数字游戏
试题 算法训练 数字游戏 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个1-N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列 ...
- java实现 蓝桥杯 算法训练 Password Suspects
问题描述 在年轻的时候,我们故事中的英雄--国王 Copa--他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好记又难以破解.后来,他才知道这种密码是一个长度为奇数 ...
- Java实现 蓝桥杯 算法训练VIP 报数(暴力+数学)约瑟夫环问题
试题 算法训练 报数 问题描述 现有n个同学站成一圈,顺时针编号1至n.从1号同学开始顺时针1/2报数,报到1的同学留在原地,报到2的同学退出圆圈,直到只剩一名同学为止.问最后剩下的同学编号. 输入格 ...
随机推荐
- java 8 stream、lambda表达式对list操作分组、过滤、求和、最值、排序、去重
1.分组 通过groupingBy分组指定字段 list.stream().collect(Collectors.groupingBy(User::getSex)); 2.过滤 通过filter方法过 ...
- Two Operations Gym - 102263M 优先队列水题
Two Operations Gym - 102263M Ayoub has a string SS consists of only lower case Latin letters, and he ...
- JSP+Servlet+JDBC+mysql实现的个人日记本系统
项目简介 项目来源于:https://gitee.com/wishwzp/Diary 本系统基于JSP+Servlet+Mysql 一个基于JSP+Servlet+Jdbc的个人日记本系统.涉及技术少 ...
- java ->会话技术Cookie&Session
会话技术Cookie&Session 会话技术简介 存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户 ...
- java ->IO流_序列化流与反序列化流
序列化流与反序列化流 用于从流中读取对象的操作流 ObjectInputStream 称为 反序列化流 用于向流中写入对象的操作流 ObjectOutputStream 称为 序列化流(对象 ...
- [tgpl]go匿名函数
[tgpl]go匿名函数 0. 定义 匿名函数顾名思义是没有名字的函数, Named functions can be declared only at the package level, but ...
- 曹工谈Spring Boot:Spring boot中怎么进行外部化配置,一不留神摔一跤;一路debug,原来是我太年轻了
spring boot中怎么进行外部化配置,一不留神摔一跤:一路debug,原来是我太年轻了 背景 我们公司这边,目前都是spring boot项目,没有引入spring cloud config,也 ...
- Python 如何随机打乱列表(List)排序
场景: 现在有一个list:[1,2,3,4,5,6],我需要把这个list在输出的时候,是以一种随机打乱的形式输出. 专业点的术语:将一个容器中的数据每次随机逐个遍历一遍. 注意:不是生成一个随机的 ...
- 关于MySQL数据被删除后空间重用的问题实验
以前知道,MySQL在通过delete语句删除数据后,空间并不会被腾出,而只是在数据文件中被标记为已删除,除非执行optimize table.前两天听说,虽然delete数据后硬盘空间不会被腾出,但 ...
- java——assert(断言)方法
包:org.junit.Assert; assertEqual(a,b,[msg='测试失败时打印的信息']): 断言a和b是否相等,相等则测试用例通过. assertNotEqual(a,b,[ms ...