hdu 1754

  简单线段树。

  只有两种操作,求一个区间的最大值,更改某一个点的值。由于是更改某一个点的值而不是改一个区间的值,所以就更新到了叶节点,反正对时间卡的也不严。

#include<stdio.h>
#include<string.h>
#define N 200010
#define max(a,b)    (a)>(b)?(a):(b)

int n,m;
int w[N];
struct node{
    int L,R;
    int nmax;
};
node tree[N*4];
int ans;
void build(int id,int L,int R)
{
    tree[id].R=R;tree[id].L=L;
    if(L==R)
    {
        tree[id].nmax=w[L];
        return ;
    }
    build(id*2,L,(L+R)/2);
    build(id*2+1,(L+R)/2+1,R);
    tree[id].nmax=max(tree[id*2].nmax,tree[id*2+1].nmax);
}
void query(int id,int L,int R)
{
    if(tree[id].L==L && tree[id].R==R)
    {
        ans=max(ans,tree[id].nmax);
        return ;
    }
    int mid=(tree[id].L+tree[id].R)/2;
    if(L>mid)
        query(id*2+1,L,R);
    else if(R<mid+1)
        query(id*2,L,R);
    else
    {
        query(id*2,L,mid);
        query(id*2+1,mid+1,R);
    }
}
void update(int id,int x,int news)
{
    if(tree[id].L==x && tree[id].R==x)
    {
        tree[id].nmax=news;
        return ;
    }
    tree[id].nmax=max(tree[id].nmax,news);
    int mid=(tree[id].L+tree[id].R)/2;
    if(x<=mid)
        update(id*2,x,news);
    else
        update(id*2+1,x,news);
}
int main()
{
    char C[5];
    int A,B;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)   scanf("%d",&w[i]);
        build(1,1,n);
        while(m--)
        {
            scanf("%s%d%d",C,&A,&B);
            if(C[0]=='Q')
            {
                ans=0;
                query(1,A,B);
                printf("%d
",ans);
            }
            else
                update(1,A,B);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yongren1zu/p/3287999.html