链接:http://www.cnblogs.com/54zyq/p/3222818.html

题意:中文题~

思路:线段树点修改,求区间中的最大值。

#include<cstdio>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=200000+5;
int MAX[maxn<<2];
void PushUP(int rt)
{
    MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
void build(int l,int r,int rt)
{//(l,r)为题目要求的总区间,rt为第一个点
    if(l==r)
    {
        scanf("%d",&MAX[rt]);
        return;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUP(rt);
}
void update(int p,int s,int l,int r,int rt)
{
    if(l==r)
    {
        MAX[rt]=s;
        return;
    }
    int m=(l+r)>>1;
    if(p<=m) update(p,s,lson);
    else update(p,s,rson);
    PushUP(rt);//每次修改一个点后这一段的最大值可能会变化,所以必须更新
}
int query(int L,int R,int l,int r,int rt)
{//[L,R]要查询的区间,在一次查询过程中不会改变,[l,r]当前节点对应的区间,每次递归这个区间就变化一次

    if(L<=l && r<=R)//当前节点对应的区间完全包含在查询区间内
        return MAX[rt];
    int m=(l+r)>>1;
    int ans=0;
    if(L<=m) ans=max(ans,query(L,R,lson));
    if(R>m) ans=max(ans,query(L,R,rson));//递归比较大小
    return ans;
}
int main()
{
//    freopen("hdu.cpp","r",stdin);
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        build(1,n,1);//建树
        while(m--)
        {
            char op[2];
            int a,b;
            scanf("%s%d%d",op,&a,&b);
            if(op[0]=='Q')
               printf("%d\n",query(a,b,1,n,1));
            else update(a,b,1,n,1);
        }
    }
    return 0;
}

前一段时间也看了一下线段树,似懂非懂,认识不深,现在再来学习后,有了新的感觉。

 posted on 2013-08-18 16:45  ∑求和  阅读(182)  评论(0编辑  收藏  举报