问题描述

有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实现 蓝桥杯 算法训练 操作格子的更多相关文章

  1. Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)

    试题 算法训练 猴子吃包子 问题描述 从前,有一只吃包子很厉害的猴子,它可以吃无数个包子,但是,它吃不同的包子速度也不同:肉包每秒钟吃x个:韭菜包每秒钟吃y个:没有馅的包子每秒钟吃z个:现在有x1个肉 ...

  2. Java实现蓝桥杯 算法训练 大等于n的最小完全平方数

    试题 算法训练 大等于n的最小完全平方数 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 输出大等于n的最小的完全平方数. 若一个数能表示成某个自然数的平方的形式,则称这个数为完全平 ...

  3. Java实现 蓝桥杯 算法训练 Beaver's Calculator

    试题 算法训练 Beaver's Calculator 问题描述 从万能词典来的聪明的海狸已经使我们惊讶了一次.他开发了一种新的计算器,他将此命名为"Beaver's Calculator ...

  4. Java实现 蓝桥杯 算法训练 Lift and Throw

    试题 算法训练 Lift and Throw 问题描述 给定一条标有整点(1, 2, 3, -)的射线. 定义两个点之间的距离为其下标之差的绝对值. Laharl, Etna, Flonne一开始在这 ...

  5. Java实现 蓝桥杯 算法训练 Remember the A La Mode(暴力)

    试题 算法训练 Remember the A La Mode 问题描述 Hugh Samston经营着一个为今年的ICPC世界总决赛的参与者提供甜点的餐饮服务.他将会提供上面有冰激凌的饼片.为了满足不 ...

  6. Java实现 蓝桥杯 算法训练 删除数组零元素

    算法训练 删除数组零元素 时间限制:1.0s 内存限制:512.0MB 提交此题 从键盘读入n个整数放入数组中,编写函数CompactIntegers,删除数组中所有值为0的元素,其后元素向数组首端移 ...

  7. Java实现 蓝桥杯 算法训练 数字游戏

    试题 算法训练 数字游戏 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个1-N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列 ...

  8. java实现 蓝桥杯 算法训练 Password Suspects

    问题描述 在年轻的时候,我们故事中的英雄--国王 Copa--他的私人数据并不是完全安全地隐蔽.对他来说是,这不可接受的.因此,他发明了一种密码,好记又难以破解.后来,他才知道这种密码是一个长度为奇数 ...

  9. Java实现 蓝桥杯 算法训练VIP 报数(暴力+数学)约瑟夫环问题

    试题 算法训练 报数 问题描述 现有n个同学站成一圈,顺时针编号1至n.从1号同学开始顺时针1/2报数,报到1的同学留在原地,报到2的同学退出圆圈,直到只剩一名同学为止.问最后剩下的同学编号. 输入格 ...

随机推荐

  1. java 8 stream、lambda表达式对list操作分组、过滤、求和、最值、排序、去重

    1.分组 通过groupingBy分组指定字段 list.stream().collect(Collectors.groupingBy(User::getSex)); 2.过滤 通过filter方法过 ...

  2. Two Operations Gym - 102263M 优先队列水题

    Two Operations Gym - 102263M Ayoub has a string SS consists of only lower case Latin letters, and he ...

  3. JSP+Servlet+JDBC+mysql实现的个人日记本系统

    项目简介 项目来源于:https://gitee.com/wishwzp/Diary 本系统基于JSP+Servlet+Mysql 一个基于JSP+Servlet+Jdbc的个人日记本系统.涉及技术少 ...

  4. java ->会话技术Cookie&Session

    会话技术Cookie&Session 会话技术简介 存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户 ...

  5. java ->IO流_序列化流与反序列化流

    序列化流与反序列化流 用于从流中读取对象的操作流 ObjectInputStream    称为 反序列化流 用于向流中写入对象的操作流 ObjectOutputStream   称为 序列化流(对象 ...

  6. [tgpl]go匿名函数

    [tgpl]go匿名函数 0. 定义 匿名函数顾名思义是没有名字的函数, Named functions can be declared only at the package level, but ...

  7. 曹工谈Spring Boot:Spring boot中怎么进行外部化配置,一不留神摔一跤;一路debug,原来是我太年轻了

    spring boot中怎么进行外部化配置,一不留神摔一跤:一路debug,原来是我太年轻了 背景 我们公司这边,目前都是spring boot项目,没有引入spring cloud config,也 ...

  8. Python 如何随机打乱列表(List)排序

    场景: 现在有一个list:[1,2,3,4,5,6],我需要把这个list在输出的时候,是以一种随机打乱的形式输出. 专业点的术语:将一个容器中的数据每次随机逐个遍历一遍. 注意:不是生成一个随机的 ...

  9. 关于MySQL数据被删除后空间重用的问题实验

    以前知道,MySQL在通过delete语句删除数据后,空间并不会被腾出,而只是在数据文件中被标记为已删除,除非执行optimize table.前两天听说,虽然delete数据后硬盘空间不会被腾出,但 ...

  10. java——assert(断言)方法

    包:org.junit.Assert; assertEqual(a,b,[msg='测试失败时打印的信息']): 断言a和b是否相等,相等则测试用例通过. assertNotEqual(a,b,[ms ...