线段树入门题
#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn = 2e5+10;
struct SegmentTree
{
int l,r;
int dat;
} t[maxn*4];
/*
建树 build(1,1,n)
并在每个节点上保存了对应区间的最大值
*/
void build(int p,int l,int r)
{
t[p].l = l;
t[p].r = r;//节点p代表的区间【L,R】
if(l == r)//叶节点
{
scanf("%d",&t[p].dat);// = a[l];
return ;
}
int mid = (l+r)>>1;
build(p*2,l,mid);//左子节点
build(p*2+1,mid+1,r);//右子节点
t[p].dat = max(t[p*2].dat,t[p*2+1].dat);//从下往上传递信息
}
/*单点修改 A[x] = v*/
void change(int p,int x,int v)
{
if(t[p].l == t[p].r)//找到叶节点
{
t[p].dat = v;
return ;
}
int mid = (t[p].l+t[p].r)>>1;
if(x <= mid)
change(p*2,x,v);
else
change(p*2+1,x,v);
t[p].dat = max(t[p*2].dat,t[p*2+1].dat);
}
/*区间查询
查询 A 在区间[l,r] 上的最大值
cout<<ask(1,l,r)<<endl;
*/
int ask(int p,int l,int r)
{
if(l <= t[p].l && r >= t[p].r)
return t[p].dat;//完全包含
int mid = (t[p].l+t[p].r)>>1;
int val = -(1<<30);//负无穷大
if(l <= mid)
val = max(val,ask(p*2,l,r));//左子节点有重叠
if(r > mid)
val = max(val,ask(p*2+1,l,r));//右子节点有重叠
return val;
}
int main()
{
int a,b;
int n,m;
char str[5];
while(scanf("%d%d",&n,&m) != EOF)
{
build(1,1,n);
while(m--)
{
scanf("%s%d%d",str,&a,&b);
if(str[0] == 'U')
change(1,a,b);
else
printf("%d\n",ask(1,a,b));
}
}
return 0;
}