没想到竟然能一次AC,而且只花了20分钟不到。第一道线段树的题了,纪念一下。
考察线段树的基本操作:建树,区间最值查询和更新操作.
View Code
#include <iostream>
using namespace std;
const int MAX = 200005;
struct Tree
{
int left; int right; int score;
}tr[MAX*3];
int n,m,s[MAX],a,b;
char cmd;
int max(int x,int y)
{
if(x > y) return x;
else return y;
}
void build(int l,int r,int now)
{
tr[now].left = l; tr[now].right = r;
if(l == r)
{
tr[now].score = s[l]; return;
}
int mid = (l + r) >> 1;
build(l,mid,(now<<1));
build(mid+1,r,(now<<1)+1);
tr[now].score = max(tr[now<<1].score,tr[(now<<1)+1].score);
}
void modify(int l,int r,int now)
{
if(l == r) { tr[now].score = b; return; }
int mid = (l + r) >> 1;
if(a <= mid)
{
modify(l,mid,now<<1);
}
else if (a > mid)
{
modify(mid+1,r,(now<<1)+1);
}
tr[now].score = max(tr[now<<1].score,tr[(now<<1)+1].score);
}
int query(int sta,int end,int now)
{
if(tr[now].left == sta && tr[now].right == end) return tr[now].score;
int mid = (tr[now].left + tr[now].right)>>1;
if(end <= mid)
{
return query(sta,end,now<<1);
}
else if(sta > mid)
{
return query(sta,end,(now<<1)+1);
}
else
{
int x = query(sta,mid,now<<1);
int y = query(mid+1,end,(now<<1)+1);
return max(x,y);
}
}
int main()
{
int i;
while(scanf("%d %d",&n,&m) != EOF)
{
for(i = 1;i <= n;++i) scanf("%d",&s[i]);
build(0,n,1);
for(i = 0;i < m;++i)
{
cin>>cmd; scanf("%d %d",&a,&b);
if(cmd == 'Q') printf("%d\n",query(a,b,1));
else modify(0,n,1);
}
}
return 0;
}