算法训练 操作格子

来源:互联网 发布:如何建立数据库 编辑:程序博客网 时间:2024/05/06 05:31
 算法训练 操作格子  
时间限制:1.0s   内存限制:256.0MB
      
问题描述

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

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Main {/** * @param args */static Node[] tree;public static void main(String[] args) throws IOException {// TODO Auto-generated method stubBufferedReader bf = new BufferedReader(new InputStreamReader(System.in));String s[] = bf.readLine().split(" ");int n = Integer.parseInt(s[0]);int m = Integer.parseInt(s[1]);tree = new Node[n * 4];Build(1, n, 1);String s1[] = bf.readLine().split(" ");for (int i = 0; i < n; i++) {int temp = Integer.parseInt(s1[i]);Insert(1, i + 1, temp);}for (int i = 1; i <= m; i++) {String s2[] = bf.readLine().split(" ");int op = Integer.parseInt(s2[0]);int x = Integer.parseInt(s2[1]);int y = Integer.parseInt(s2[2]);switch (op) {case 1:Insert(1, x, y);break;case 2:System.out.println(getsum(1, x, y));break;case 3:System.out.println(getmax(1, x, y));break;}}}private static int getmax(int p, int start, int end) {// TODO Auto-generated method stubif (tree[p].left == start && tree[p].right == end) {return tree[p].max;}int mid = (tree[p].left + tree[p].right) / 2;if (end <= mid)return getmax(p * 2, start, end);if (start > mid) {return getmax(p * 2 + 1, start, end);}return Math.max(getmax(p * 2, start, mid),getmax(p * 2 + 1, mid + 1, end));}private static int getsum(int p, int start, int end) {// TODO Auto-generated method stubif (tree[p].left == start && tree[p].right == end) {return tree[p].sum;}int mid = (tree[p].left + tree[p].right) / 2;if (end <= mid)return getsum(p * 2, start, end);if (start > mid) {return getsum(p * 2 + 1, start, end);}return getsum(p * 2, start, mid) + getsum(p * 2 + 1, mid + 1, end);}private static void Insert(int p, int diretion, int value) {// TODO Auto-generated method stubif (tree[p].left == diretion && tree[p].right == diretion) {tree[p].max = value;tree[p].sum = value;return;}int mid = (tree[p].left + tree[p].right) / 2;if (diretion <= mid)Insert(p * 2, diretion, value);else {Insert(p * 2 + 1, diretion, value);}tree[p].max = Math.max(tree[p * 2].max, tree[p * 2 + 1].max);tree[p].sum = tree[p * 2].sum + tree[p * 2 + 1].sum;}private static void Build(int l, int r, int p) {// TODO Auto-generated method stubtree[p] = new Node();tree[p].left = l;tree[p].right = r;tree[p].max = 0;tree[p].sum = 0;if (l == r)return;int mid = (l + r) / 2;Build(l, mid, 2 * p);Build(mid + 1, r, 2 * p + 1);}}class Node {int left;int right;int sum;int max;}


0 0