题目描述
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
输入
本题目包含多组测试,请处理到文件结束。 在每个测试的第一行,有两个正整数 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。
输出
对于每一次询问操作,在一行里面输出最高成绩。
样例输入
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
样例输出
5 6 5 9
提示
Huge input,the C function scanf() will work better than cin
思路
线段树,点更新操作,线段数维护区间最大值。
代码
#include <iostream>
#include <math.h>
#include <algorithm>
#include <map>
#include <queue>
#include <string.h>
#include <stdio.h>
#include <fstream>
#define mx 20000002
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
struct node
{
int l;
int r;
int m;
};
node a[
800020];
int num[
200005];
void pushup (
int i)
{
a[i].m = max(a[i<<
1].m,a[i<<
1|
1].m);
}
void build (
int l,
int r,
int i)
{
a[i].l=l;
a[i].r=r;
a[i].m=-
1;
if(l==r)
{
a[i].m=num[l];
return ;
}
int mid = (l+r)>>
1;
build(l,mid,i<<
1);
build(mid+
1,r,i<<
1|
1);
pushup(i);
}
void update (
int x,
int v,
int i)
{
if(a[i].l == x&&a[i].r==x)
{
a[i].m=v;
return ;
}
int mid = (a[i].l+a[i].r)>>
1;
if(x<=mid) update(x,v,i<<
1);
else update(x,v,i<<
1|
1);
pushup(i);
}
int query (
int l,
int r,
int i)
{
if(l<=a[i].l&&a[i].r<=r)
return a[i].m;
int mid = (a[i].l +a[i].r)>>
1;
if(r<=mid )
return query(l,r,i<<
1);
else if(l>mid)
return query(l,r,i<<
1|
1);
else return max(query(l,mid,i<<
1),query(mid+
1,r,i<<
1|
1));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen(
"a",
"r",stdin);
#endif
ios_base::sync_with_stdio(
false);
cin.tie(
0);
mem(a);
mem(num);
char c;
int n,t,x,y;
while(
cin>>n>>t)
{
for(
int i=
1; i<=n; ++i)
cin>>num[i];
build(
1,n,
1);
while(t--)
{
cin>>c>>x>>y;
if(c==
'Q')
cout<<query(x,y,
1)<<endl;
else if(c==
'U')
update(x,y,
1);
}
}
return 0;
}