线段树
#include<stdio.h>
#include<string.h>
#define MAXN 200005
struct ST //存储类型
{
int l,r,max; //max表示当前节点的最大值
}st[4*MAXN];
inline int max(int a,int b)
{
return a>b?a:b;
}
void build(int ll,int rr,int n) //初始化建立线段树
{
st[n].l=ll; //表示当前节点的最左端,
st[n].r=rr; //表示当前节点的最右端,
st[n].max=0; //当前节点的值,初始化全为零,
if (ll==rr) return ; //如果遇到了根节点
int mid=(ll+rr)/2; //将当前节点分开,mid为左孩子的右端点,为右孩子的左端点;
build(ll,mid,2*n); //先遍历左边的树
build(mid+1,rr,2*n+1); //再遍历右边的树
}
void insert(int ll,int rr,int a,int n) // 更新
{
if (st[n].l==ll&&st[n].r==rr)
{st[n].max=a;return ;}//如果找到,就赋值,退出。
else if (a>st[n].max)
st[n].max=a; //从新更新;
int mid=(st[n].l+st[n].r)/2;
if (rr<=mid) //如果右端点比他的中间区分值mid还小,那么久插到左边,
insert(ll,rr,a,2*n);
else if (ll>=mid+1) //如果左端点比他的中间区分值mid还大,那么久插到右边,
insert(ll,rr,a,2*n+1);
}
int find(int ll,int rr,int n) // 查询
{
if (st[n].l==ll&&st[n].r==rr)
return st[n].max; //返回max;
int mid=(st[n].l+st[n].r)/2;
if (rr<=mid) //如果rr小于中点分解值,那么就查找左孩子,
find(ll,rr,2*n);
else if (ll>=mid+1) //如果rr大于于中点分解值,那么就查找右孩子,
find(ll,rr,2*n+1);
else
return max(find(ll,mid,2*n),find(mid+1,rr,2*n+1));
}
int main()
{
int n,m,a,b,i;
char op;
while (scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
for (i=1;i<=n;++i)
{
scanf("%d",&a);
insert(i,i,a,1);
}
getchar();
for (i=1;i<=m;++i)
{
scanf("%c %d %d",&op,&a,&b);
getchar();
if (op=='Q') printf("%d\n",find(a,b,1));
if (op=='U') insert(a,a,b,1);
}
}
return 0;
}