蓝桥杯java提交格式_算法笔记_064:蓝桥杯练习 操作格子(Java)

packagecom.liuzhen.systemExe;importjava.util.Scanner;public classMain{public int[][] segTree;/** 参数root:代表线段树的根节点,此处使用数组存放线段树,其根节点从0开始计数,那么其两个子节点编号必定满足2*root+1或者2*root+2

* 参数array:给定的目标数组,需要转成相应功能的线段树

* 参数start:线段树划分给定数组区间的起始位置

* 参数end:线段树划分给定数组区间的末尾位置

* 函数功能:返回一个线段树,其所有节点均存放当前数组子区间内的总和以及最大值*/

public void buildSegTree(int root, int[] array, int start, intend) {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, intqend) {if(qstart > end || 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;elsemax=temp2;

}returnmax;

}/** 参数root:开始进行查找的根节点对应的数组下标值

* 参数start-end:当前节点所表示的区间

* 参数qstart-qend:此次查询的区间

* 函数功能:查询当前区间qstart-qend的总和*/

public int querySegTreeSum(int root, int start, int end, int qstart, intqend) {if(qstart > end || qend

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

}

}returnsum;

}/** 参数root:开始进行查找的根节点对应的数组下标值

* 参数qstart-qend:当前节点所表示的区间

* 函数功能:把数组下标为index的元素值变成value,并更新线段树*/

public void updateSegTree(int root, int qstart, int qend, int index, intvalue) {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 voidmain(String[] args){

Main test= newMain();

Scanner in= newScanner(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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值