问题描述

有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. [codeforces-315D div2]模拟

    题目:给两个字符串a.b,问从a中删去若干字符后最多可以得到多少个b串的重复串(bb...b的形式,b的长度不超过100),其中a串是由一个长度不超过100的字符串s重复k次得到的 思路: 暴力匹配a ...

  2. 网站设计时应考虑哪些因素,以保证网站是对SEO友好

    根据用户的搜索习惯做好栏目的设计 根据用户的习惯做好三大标签的设计 做好首页栏目的展现布局  对于用户来说的重点 展示栏目的合理化 多样化 细节化 代码的静态化 域名 服务器购买稳定 合格 网站内容的 ...

  3. 开始写博客的第一天,如何用c实现“hello wolrd”

    “hello world” 应该是大多数人学习的第一个代码 那也就作为我第一篇博客的开端吧 实现的代码如下 #include <stdio.h> int main() { printf(& ...

  4. MySQL++:liunx 安装 MySQL

    第一步: 1):下载mysql安装包:这里选择下载版本 5.6.33,通用版,linux下64位 http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql- ...

  5. webpack指南(六)命令行环境配置

    webpack 命令行环境配置中,通过设置 --env 可以使你根据需要,传入尽可能多的环境变量.在 webpack.config.js 文件中可以访问到这些环境变量. webpack --env.N ...

  6. git init 后关联github仓库是发生错误:

    : failed to push some refs to 'git@github.com:AlanKnightly/reactC.git'hint: Updates were rejected be ...

  7. node响应头缓存设置

    我把react项目分成4个板块,在路由的顶层 今天在手机上打开react项目的时候,发现平级路由跳转时某一个图片较多的板块图片总是渲染得很慢,这分明是重新发起请求了. 然后我先查一下react-rou ...

  8. flask之Blueprint蓝图

    flask_Blueprint.py ''' flask中的Blueprint蓝图: (1)新建模块,例如Bp1.py,Bp2.py,在模块中创建蓝图实例 (2)通过app.register_blue ...

  9. nginx操作目录

    nginx配置文件/conf/nginx.conf 错误日志功能:los/error.log 访问日志功能:logs/access.log 站点服务请求功能配置:html/ 禁止访问功能配置 404页 ...

  10. 点双连通分量F. Simple Cycles Edges

    F. Simple Cycles Edges time limit per test 2 seconds memory limit per test 256 megabytes input stand ...