有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
1 2 3 4
2 1 3
1 4 3
3 1 4
样例输出
6
3
3
数据规模与约定
对于20%的数据n <= 100,m <= 200。
对于50%的数据n <= 5000,m <= 5000。
对于100%的数据1 <= n <= 100000,m <= 100000,0 <= 格子权值 <= 10000。
package Yexy;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner Scan = new Scanner (System.in);
int m = 0 , n = 0,j = 0;
NODE xTree = null;
Tree tree = new Tree();
int input[][] = new int [10000][3];
int Gezi = 0;
n = Scan.nextInt();
m = Scan.nextInt();
if(n>0 && m>0){
xTree = tree.CreatTree(1, n);
for(int i = 1;i<=n ;++i ){
Gezi = Scan.nextInt();
tree.Insert(xTree, i, Gezi);
}
for(int i= 0 ;i<m ; i++){
for(j = 0 ;j<3 ;j++ ){
input[i][j] = Scan.nextInt();
}
}
for(int i=0 ;i<m ;i++ ){
switch(input[i][0]){
case 1: tree.Modify(xTree, input[i][1], input[i][2]);
break;
case 2: System.out.println(tree.GeziSum(xTree, input[i][1], input[i][2]));
break;
case 3: System.out.println(tree.GeziMax(xTree, input[i][1], input[i][2]));
break;
default :break;
}
}
}
}
}
class NODE {
int max = 0, sum = 0;
int left, right;
NODE lChild;
NODE rChild;
}
class Tree{
NODE CreatTree(int left ,int right){
NODE xTree = new NODE();
xTree.left = left;
xTree.right = right;
xTree.max = 0;
xTree.sum = 0;
xTree.lChild = null;
xTree.rChild = null;
if(right!=left){
int mid = (left + right)/2;
xTree.lChild = CreatTree(left , mid);
xTree.rChild = CreatTree(mid+1, right);
}
return xTree;
}
int maxValue(int max , int temp){
if (temp > max){
max = temp;
}
return max;
}
void Insert (NODE xTree , int point , int value){
xTree.sum += value;
xTree.max = maxValue(xTree.max , value);
if( xTree.left == xTree.right){
return ;
}else{
if(point <= (xTree.left+xTree.right)/2){
Insert(xTree.lChild, point, value);
}else{
Insert(xTree.rChild, point, value);
}
}
return;
}
void Modify(NODE xTree , int point , int value){
if (xTree.left == point && xTree.right == point){
xTree.max = value;
xTree.sum = value;
return ;
}else{
int mid = (xTree.left + xTree.right)/2;
if(point<=mid){
Modify(xTree.lChild, point, value);
}else{
Modify(xTree.rChild, point, value);
}
xTree.max = maxValue(xTree.lChild.max,xTree.rChild.max);
xTree.sum = xTree.lChild.sum+xTree.rChild.sum;
}
return ;
}
int GeziSum(NODE xTree , int left , int right){
if(left == xTree.left && right == xTree.right){
return xTree.sum;
}else{
int mid = (xTree.left+xTree.right)/2;
if(right<=mid){
return GeziSum(xTree.lChild, left, right);
}else if(left>mid){
return GeziSum(xTree.rChild, left, right);
}else{
return GeziSum(xTree.lChild, left, mid)+GeziSum(xTree.rChild, mid+1, right);
}
}
}
int GeziMax(NODE xTree , int left , int right){
if(left == xTree.left && right == xTree.right){
return xTree.max;
}else{
int mid = (xTree.left+xTree.right)/2;
if(right<=mid){
return GeziMax(xTree.lChild, left, right);
}else if(left>mid){
return GeziMax(xTree.rChild, left, right);
}else{
return maxValue(GeziMax(xTree.lChild, left, mid),GeziMax(xTree.rChild, mid+1, right));
}
}
}
}