这题涉及单点更新,相对来说比较容易把
/*If I get TLE , it is good.If I get AC,it's NICE !*/
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
const int MAXN=1e6+100;
struct t
{
int l,r,v;
} sgetree[800000+5];
int a[300000+5];
int index,grade;
int l,r;
int ans=0;
using namespace std;
//询问主要是把一个区间拆成几个区间去找,然后找到每个子区间的ans,找最大的
void query(int l,int r,int root)
{
if(sgetree[root].l==l && sgetree[root].r==r)
{
ans=max(ans,sgetree[root].v);
return ;
}
int mid=(sgetree[root].l+sgetree[root].r)/2;
if(r<=mid) query(l,r,root*2);
else if(l>mid) query(l,r,root*2+1);
else
{
query(l,mid,root*2);
query(mid+1,r,root*2+1);
}
}
// 更新主要是自顶向下找到该叶子节点,再自下向上回溯更新父亲节点对应的max
void update(int root)
{
if(sgetree[root].l==index && sgetree[root].r==index )
{
sgetree[root].v=grade;
return ;
}
int mid=(sgetree[root].l+sgetree[root].r)/2;
if(index<=mid) update(root*2);
else update(root*2+1);
sgetree[root].v=max(sgetree[root*2].v,sgetree[root*2+1].v);
}
// 递归建树
void build(int l,int r,int root)
{
sgetree[root].l=l;
sgetree[root].r=r;
if(l==r)
{
sgetree[root].v=a[l];// a[right]一样
return ;
}
int mid=(l+r)/2;
build(l,mid,root*2);
build(mid+1,r,root*2+1);
sgetree[root].v=max(sgetree[root*2].v,sgetree[root*2+1].v);
}
int main(void)
{
int n,m;
while((scanf("%d%d",&n,&m))==2)
{
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,n,1);
while(m--)
{
ans=0;
char str[2];
scanf("%s",str);
if(strcmp(str,"U")==0)
{
scanf("%d%d",&index,&grade);
update(1);
}
else if(strcmp(str,"Q")==0)
{
scanf("%d%d",&l,&r);
query(l,r,1);
printf("%d\n",ans);
}
}
}
}