解析:线段树模板题,线段树单点更新,找出区间最大值和更改区间点的值。
#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; }