HDU1754 - I Hate It(单点更新&区间查询)

题目大意

给定一个序列A1,A2,..,An.可以对其进行一下两种操作:

1、query(a,b) 查询区间[a,b]的最大值

2、update(a,b) 把点a的值修改为b

题解

线段树的基础操作,单点更新和区间查询,第一次写线段树!!!激动ing!!!(虽然是照着《训练指南》和shǎ崽大神的代码写的。。。)

代码:

#include<iostream>

#include<cstring>

#include<cstdio>

#include<cmath>

#include<algorithm>

#define lson l, m , s << 1

#define rson m + 1 , r , s << 1 | 1

#define MAXN 200005

using namespace std;

int maxv[MAXN<<2];

void PushUP(int s)

{

    maxv[s] = max(maxv[s<<1] , maxv[s<<1|1]);

}

void build(int l,int r,int s)

{

    if(l==r)

    {

        scanf("%d",&maxv[s]);

        return;

    }

    int m=(l+r)>>1;

    build(lson);

    build(rson);

    PushUP(s);

}

int query(int ql,int qr,int l,int r,int s)

{

    if(ql<=l&&r<=qr) return maxv[s];

    int m=(l+r)>>1,ans=0;

    if(ql<=m) ans=max(ans,query(ql,qr,lson));

    if(m<qr)  ans=max(ans,query(ql,qr,rson));

    return ans;

}

void update(int p,int v,int l,int r,int s)

{

    if(l==r)

    {

        maxv[s]=v;

        return;

    }

    int m=(l+r)>>1;

    if(p<=m) update(p,v,lson);

    else

        update(p,v,rson);

    PushUP(s);

}

int main(void)

{

    int n,m;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        build(1,n,1);

        while(m--)

        {

            char ss[3];

            int a,b;

            scanf("%s%d%d",ss,&a,&b);

            if(ss[0]=='Q') printf("%d\n",query(a,b,1,n,1));

            else

                update(a,b,1,n,1);

        }

    }

    return 0;

}

你可能感兴趣的:(HDU)