E

题目连接 http://acm.hust.edu.cn/vjudge/contest/121192#problem/E

这一题也是线段树的应用,和上一题类似,都是建树,更新,查询。但是这一题求的是最大值,所以上一题父区间时所有子区间的和应改为子区间的最大值。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define Max 200005
int n;
int a[Max] ;
int t[Max<<2];
void build(int l,int r,int pt)//建树
{
    if(l==r)
    {
        t[pt]=a[pt];
        return ;
    }
    int mid=(l+r)>>1;
    t[pt]=-1;
    if(l<=mid)
    {
        build(l,mid,pt<<1);
        t[pt]=max(t[pt],t[pt<<1]);//此处根据题目变动

    }
    if(r>mid)
    {
        build(mid+1,r,pt<<1|1);
        t[pt]=max(t[pt],t[pt<<1|1]);
    }
void Update(int id,int ch,int l,int r,int pt )//更新
{
    if(l==r)
    {
        t[id]=ch;
        return ;
    }
    int mid=(r+l)>>1;
    if(mid>=id)
        Update(id,ch,l,mid,pt<<1);
        else
        Update(id,ch,mid+1,r,pt<<1|1);
    t[pt]=max(t[pt<<1],t[pt<<1|1]);

}
int Query(int x,int y,int pt,int l,int r)//查询
{
    if(x<=l&&y>=r) return t[pt];
    int mid=(l+r)>>1;
    int tm1=-1,tm2=-1;
    if(x<=mid) tm1=Query(x,y,pt<<1,l,mid);
    if(y>mid)  tm2=Query(x,y,pt<<1|1,mid+1,r);
    return max(tm1,tm2);
}
int main()
{
    int n,m,x,y,id,ch,i;
    char c;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++)
            cin>>a[i];
            build(1,n,1);
            while(m--)
            {
                cin>>c;
                if(c=='Q')
                {
                    cin>>x>>y;
                    cout<<Query(x,y,1,1,n)<<endl;
                }
                if(c=='U')
                {
                    cin>>id>>ch;
                    Update(id,ch,1,n,1);
                }

            }

    }

    return 0;
}
原文地址:https://www.cnblogs.com/Twsc/p/5699104.html