Problem Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 这让很多学生很反感。 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
Input
本题目包含多组测试,请处理到文件结束。 在每个测试的第一行,有两个正整数 N 和 M ( 0<n<=200000,0<m<5000 ),分别代表学生的数目和操作的数目。="" 学生id编号分别从1编到n。="" 第二行包含n个整数,代表这n个学生的初始成绩,其中第i个数代表id为i的学生的成绩。="" 接下来有m行。每一行有一个字符="" c="" (只取'q'或'u')="" ,和两个正整数a,b。="" 当c为'q'的时候,表示这是一条询问操作,它询问id从a到b(包括a,b)的学生当中,成绩最高的是多少。=""
当c为'u'的时候,表示这是一条更新操作,要求把id为a的学生的成绩更改为b。="" <="" div="">
Output
对于每一次询问操作,在一行里面输出最高成绩。
Sample Input
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[/hint]
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MX 200005
using namespace std;
struct node {
int l, r, v;
} a[MX << 2];
int Max;
int max(int x, int y)
{
return x > y ? x : y;
}
void PashUp(int root)
{
a[root].v = max(a[root << 1].v, a[root << 1 | 1].v);
}
void build_tree(int l, int r, int root)
{
a[root].l = l;
a[root].r = r;
a[root].v = 0;
if (l == r ) {
scanf("%d", &a[root].v);
return ;
}
int mid = (l + r) >> 1;
build_tree(l, mid, root << 1);
build_tree(mid + 1, r, root << 1 | 1);
PashUp(root);
}
void update(int l, int r, int root, int k)
{
if (a[root].l == l && a[root].r == r) {
a[root].v = k;
return ;
}
int mid = (a[root].l + a[root].r) >> 1;
if (r <= mid)update(l, r, root << 1, k);
else if (l > mid)update(l, r, root << 1 | 1, k);
PashUp(root);
}
int Query(int l, int r, int root)
{
if (a[root].l >= l && a[root].r <= r) {
return a[root].v;
}
int mid = (a[root].l + a[root].r) >> 1;
if (r <= mid)return Query(l, r, root << 1);
else if (l > mid)return Query(l, r, root << 1 | 1);
else {
return max(Query(l, r, root << 1),Query(l, r, root << 1 | 1));
}
}
int main()
{
int n, m, l, r;
char ch;
while (~scanf("%d%d", &n, &m)) {
build_tree(1, n, 1);
while (m--) {
scanf(" %c", &ch);
if (ch == 'Q') {
scanf("%d%d", &l, &r);
printf("%d\n", Query(l, r, 1));
}
if (ch == 'U') {
scanf("%d%d", &l, &r);
update(l, l, 1, r);
}
}
}
return 0;
}