这道题的就是每次询问一个区间,找出区间中的最大值
依然是线段树做法
sum数组就是线段树的节点,存的是它代表的区间中最大的值,更新一个节点的时候只要push_up一下就好了
#include <cstdio>
#include <cstring>
const int MAX = 200010;
int sum[MAX<<2];
template <class T>
T max(T a,T b)
{
return (a>b)?a:b;
}
void push_up(int rt)
{
sum[rt] = max(sum[rt<<1],sum[(rt<<1)+1]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&sum[rt]);
return;
}
int mid = (r+l)>>1;
build(l,mid,rt<<1);
build(mid+1,r,(rt<<1)+1);
push_up(rt);
}
void update(int p,int val,int l,int r,int rt)
{
if(l==r)
{
sum[rt] = val;
return;
}
int mid = (r+l)>>1;
if(p<=mid) update(p,val,l,mid,rt<<1);
else update(p,val,mid+1,r,(rt<<1)+1);
push_up(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r) return sum[rt];
int mid = (r+l)>>1;
int ans = -0x7fffffff;
if(L<=mid) ans = query(L,R,l,mid,rt<<1);
if(R>mid) ans = max(ans,query(L,R,mid+1,r,(rt<<1)+1));
return ans;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)==2)
{
build(1,n,1);
char c;
int x,y;
while(m--)
{
scanf(" %c%d%d",&c,&x,&y);
if(c=='Q')
printf("%d\n",query(x,y,1,n,1));
else update(x,y,1,n,1);
}
}
return 0;
}