解析:线段树模板题,线段树单点更新,找出区间最大值和更改区间点的值。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200000;
int a[N];
int s[N << 2], L[N << 2], R[N << 2];
void build(int u,int l,int r) {
if(l == r) {
L[u] = R[u] = l;
s[u] = a[l];
return ;
}
int mid = (l + r) / 2;
build(u*2,l,mid);
build(u*2+1,mid+1,r);
L[u] = l;
R[u] = r;
s[u] = max(s[u*2],s[u*2+1]);
}
void modify(int u,int x,int v) {
if(R[u] == x && L[u] == x) {//叶子节点,找到结果返回
s[u] = v;
return ;
}
int mid = (L[u] + R[u]) / 2;
if(x <= mid) {
modify(u*2,x,v);
}else {
modify(u*2+1,x,v);
}
s[u] = max(s[u*2],s[u*2+1]);
}
int query(int u,int l,int r) {
if(l <= L[u] && R[u] <= r) {
return s[u];
}
int mid = (L[u] + R[u]) / 2;
int ret = -N;
if(l <= mid) {
ret = max(ret,query(u*2,l,r));
}
if(r > mid) {
ret = max(ret,query(u*2+1,l,r));
}
return ret;
}
int main() {
int m,n;
int x,y;
while(scanf("%d%d",&n,&m) != EOF) {
for(int i = 1; i <= n; i++) {
scanf("%d",&a[i]);
}
memset(s,0,sizeof(s));
L[1] = 1;
R[1] = n;
build(1,L[1],R[1]);
char cmd[3];
while(m--) {
scanf("%s",cmd);
if(cmd[0] == 'Q') {
scanf("%d%d",&x,&y);
printf("%d\n",query(1,x,y));
}else if(cmd[0] == 'U') {
scanf("%d%d",&x,&y);
modify(1,x,y);
}
}
}
return 0;
}