线段树-操作格子


有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。

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));
			}
		}
	}
}



Guess you like

Origin blog.csdn.net/u012651389/article/details/44903831