没想到竟然能一次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;
}
posted on 2011-04-08 23:49  c++fans  阅读(324)  评论(0编辑  收藏  举报