题目传送:操作格子
思路:简单线段树,单点更新,区间求和以及最值
AC代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cctype>
#define LL long long
#define INF 0x7fffffff
using namespace std;
const int maxn = 100005;
int n, m;
int sum[maxn << 2], MAX[maxn << 2];
void build(int l, int r, int rt) {
if(l == r) {
scanf("%d", &sum[rt]);
MAX[rt] = sum[rt];
return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
MAX[rt] = max(MAX[rt << 1], MAX[rt << 1 | 1]);
}
void update(int p, int y, int l, int r, int rt) {
if(l == r) {
sum[rt] = y;
MAX[rt] = y;
return;
}
int mid = (l + r) >> 1;
if(p <= mid) update(p, y, l, mid, rt << 1);
else update(p, y, mid + 1, r, rt << 1 | 1);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
MAX[rt] = max(MAX[rt << 1], MAX[rt << 1 | 1]);
}
int query_sum(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return sum[rt];
}
int mid = (l + r) >> 1;
int ret = 0;
if(L <= mid) ret += query_sum(L, R, l, mid, rt << 1);
if(R >= mid + 1) ret += query_sum(L, R, mid + 1, r, rt << 1 | 1);
return ret;
}
int query_MAX(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return MAX[rt];
}
int mid = (l + r) >> 1;
int ret = 0;
if(L <= mid) ret = max(ret, query_MAX(L, R, l, mid, rt << 1));
if(R >= mid + 1) ret = max(ret, query_MAX(L, R, mid + 1, r, rt << 1 | 1));
return ret;
}
int main() {
while(scanf("%d %d", &n, &m) != EOF) {
build(1, n, 1);
while(m --) {
int p, x, y;
scanf("%d %d %d", &p, &x, &y);
if(p == 1) {
update(x, y, 1, n, 1);
}
else if(p == 2) {
printf("%d\n", query_sum(x, y, 1, n, 1));
}
else {
printf("%d\n", query_MAX(x, y, 1, n, 1));
}
}
}
return 0;
}
原文:http://blog.csdn.net/u014355480/article/details/45715969