问题描述
蒜头君有很多苹果,每个苹果都有对应的甜度值。 蒜头君现在想快速知道从第 i 个苹果到第 j 个苹果中,最甜的甜度值是多少。 因为存放时间久了,有的苹果会变甜,有的苹果会因为腐烂而变得不甜,所以蒜头君有时候还需要修改第 i个苹果的甜度值。
输入格式
第一行输入两个正整数
N,M
接下来N个整数代表这N个的初始值
接下来M行,第一个字母为U,改第i个的甜度值为j。为U,查询i到j中甜度值最大
样例输入
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
思路:线段树的维护与更新,修改父节点为子节点中的最大值即可
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
int s[4*N];
void up(int p){
s[p]=max(s[(p<<1)],s[(p<<1)+1]);//将父节点更改为子节点中的最大值
}
void modify(int p,int l,int r,int x,int v){
if(l==r){
s[p]=v;
return;
}
int mid=(l+r)/2;
if(x<=mid){
modify((p<<1),l,mid,x,v);
}else{
modify((p<<1)+1,mid+1,r,x,v);
}
up(p);
}
int query(int p,int l,int r,int x,int y){
if(x<=l&&y>=r){
return s[p];
}
int mid=(l+r)/2,res=0;
if(x<=mid){
res=max(res,query((p<<1),l,mid,x,y));
}
if(y>mid){
res=max(res,query((p<<1)+1,mid+1,r,x,y));
}
return res;
}
int main(){
int n,m,d;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&d);
modify(1,1,n,i,d);
}
char c;
int a,b;
for(int i=1;i<=m;i++){
cin>>c;
if(c=='Q'){
cin>>a>>b;
cout<<query(1,1,n,a,b)<<endl;
continue;
}
if(c=='U'){
cin>>a>>b;
modify(1,1,n,a,b);
continue;
}
}
return 0;
}