问题描述

有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. Docker & k8s 系列三:在k8s中部署单个服务实例

    本章将会讲解: pod的概念,以及如何向k8s中部署一个单体应用实例. 在上面的篇幅中,我们了解了docker,并制作.运行了docker镜像,然后将镜像发布至中央仓库了.然后又搭建了本机的k8s环境 ...

  2. ql的python学习之路-day7

    函数与函数式编程 一.编程模式分为三种: 1.面向对象编程:类----->关键字class 2.面向过程编程:过程----->关键字def,没有return 3.函数式编程:函数----- ...

  3. 使用Flutter开发的抖音国际版

    简介 最近花了两天时间研究使用Flutter开发一个抖音国际版. 先上图,个人感觉使用Flutter开发app快得不要不要的额.  两天就基本可以开发个大概出来.   最主要是热更新,太方便实时调整U ...

  4. MyCat基本知识

    一.Mycat基本元素 1.逻辑库,mycat中存在,对应用来说相当于mysql数据库,后端可能对应了多个物理数据库,逻辑库中不保存数据 2.逻辑表,逻辑库中的表,对应用来说相当于mysql的数据表, ...

  5. 201771010128王玉兰《面向对象程序设计(Java)》第十六周学习总结

    第一部分:理论基础 1.线程的概念 进程:进程是程序的一次动态执行,它对应了从代码加 载.执行至执行完毕的一个完整过程.  多线程:多线程是进程执行过程中产生的多条执行线索.  线程:线程是比进程执行 ...

  6. BZOJ 1028 BZOJ 1029 //贪心

    1028: [JSOI2007]麻将 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2197  Solved: 989[Submit][Status][ ...

  7. 模板:分页JSP(结合Servlet)

    DAO类(后续无需改变) package dao; import java.sql.Connection; import java.sql.PreparedStatement; import java ...

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

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

  9. centos7 安装rpm版的mysql遇到坑——误删root用户的恢复

    在网上找了教程http://blog.csdn.net/frankcheng5143/article/details/77609093安装过程很顺利,随着修改了root的密码后不下心误删了root账号 ...

  10. centos安装以及网络配置

    Linux安装 1.Linux安装完成后 第一个问题就是网络不通的问题 ,问题图片如下: 解决办法: 三种网络模式: 桥接模式:虚拟机和宿主机是兄弟关系,统一由宿主机连接的路由器分发ip NAT模式: ...