HDU1854 - 线段树 单点修改区间最大值
HDU1854 - 线段树 单点修改区间最大值
题目链接: I Hate It
题目大意
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5
Sample Output
5
6
5
9
Hint
Huge input,the C function scanf() will work better than cin
AC代码
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn = 200000;
struct NOOD {
int l, r, add, Max;
}tree[maxn * 4 + 5];
int N, M;
int A[maxn + 5];
void Build(int L, int R, int x) {
tree[x].l = L, tree[x].r = R, tree[x].Max = 0;
if(L == R) {
tree[x].Max = A[L];
return ;
}
int mid = (L + R) / 2;
Build(L, mid, x * 2);
Build(mid + 1, R, x * 2 + 1);
tree[x].Max = max(tree[x * 2].Max, tree[x * 2 + 1].Max);
}
void PushDown(int x) {
if(tree[x].add) {
tree[x * 2].Max = tree[x].add;
tree[x * 2 + 1].Max = tree[x].add;
tree[x * 2].add = tree[x].add;
tree[x * 2 + 1].add = tree[x].add;
tree[x].add = 0;
}
}
void Update(int L, int R, int add, int x) {
if(L <= tree[x].l && tree[x].r <= R) {
tree[x].add = add;
tree[x].Max = add;
return ;
}
PushDown(x);
int mid = (tree[x].l + tree[x].r) / 2;
if(L <= mid)Update(L, R, add, x * 2);
if(R > mid)Update(L, R, add, x * 2 + 1);
tree[x].Max = max(tree[x * 2].Max, tree[x * 2 + 1].Max);
}
int Query(int L, int R, int x) {
if(L <= tree[x].l && tree[x].r <= R)return tree[x].Max;
PushDown(x);
int mid = (tree[x].l + tree[x].r) / 2;
int res = 0;
if(L <= mid) res = max(res, Query(L, R, x * 2));
if(R > mid) res = max(res, Query(L, R, x * 2 + 1));
return res;
}
int main() {
while(~scanf("%d%d", &N, &M)) {
memset(tree, 0, sizeof(tree));
for(int i = 1; i <= N; i++)scanf("%d", &A[i]);
Build(1, N, 1);
char s[2]; int l, r;
while(M--) {
scanf("%s%d%d", s, &l, &r);
if(s[0] == 'Q')printf("%d\n", Query(l, r, 1));
else Update(l, l, r, 1);
}
}
return 0;
}