链接:点击打开链接
题意:在每个测试的第一行,有两个正整数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.
对于每一次询问操作,在一行里面输出最高成绩
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int siz=200005;
int tree[siz<<2];
void build(int l,int r,int rt){
if(l==r){
scanf("%d",&tree[rt]);
return;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
void Change(int p,int q,int l,int r,int rt){
if(l==r){
tree[rt]=q;
return;
}
int m=(l+r)>>1;
if(p<=m)
Change(p,q,l,m,rt<<1);
else
Change(p,q,m+1,r,rt<<1|1);
tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R)
return tree[rt];
int ans=0,m=(l+r)>>1;
if(L<=m)
ans=max(ans,query(L,R,l,m,rt<<1));
if(R>m)
ans=max(ans,query(L,R,m+1,r,rt<<1|1));
return ans;
}
int main(){ //单点更新求区间最值模板题
char c;
int n,m,i,j,u,v;
while(scanf("%d%d",&n,&m)!=EOF){
build(1,n,1);
while(m--){
cin>>c>>u>>v;
if(c=='Q')
printf("%d\n",query(u,v,1,n,1));
else
Change(u,v,1,n,1);
}
}
return 0;
}