原题
这是一道线段树裸体,记录一下加深印象。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,a[1000005];
struct tree//结构体存储线段树
{
int l,r,dat;
}t[1000000];//要开叶节点数的四倍大小防止越界,这里瞎开的
void build(int p,int l,int r)//建树
{
t[p].l=l,t[p].r=r;
if(l==r)
{
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);
}
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);
}
int ask(int p,int l,int r)//区间查询
{
if(l<=t[p].l&&t[p].r<=r)
return t[p].dat;
int mid=(t[p].l+t[p].r)>>1;
int val=-(1<<20);
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()
{
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(1,1,n);
while(m--)
{
char s[5];
int x,y;
scanf("%s%d%d",s,&x,&y);
if(s[0]=='Q')
cout<<ask(1,x,y)<<endl;
else
change(1,x,y);
}
}
return 0;
}