HDU:1754 I Hate It

开始刷线段树的题。上一道是单值加减,区间求和,我用树状数组过掉了。这道题是单值更新,区间求最值,只能用线段树了。

用了watashi翻译的那本书上的模版,把半闭半开的区间改成了全闭区间。另外数组开的大小问题还是不太懂。。

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <stack>
#include <algorithm>
#define MAXN 200005
#define MOD 1000000007
#define INF -2139062144
#define ll long long
//ios::sync_with_stdio(false)
using namespace std;
int N,M,mxn;
const int MAX_N = 1 << 18;
int dat[2*MAX_N-1];
void Init()
{
    mxn=1;
    while(mxn<N) mxn*=2;
    memset(dat,0,sizeof(dat));
}
void update(int val,int k)
{
    k+=mxn-1;//得到在线段树上的编号
    dat[k]=max(val,dat[k]);//更改当前结点的值
    while(k/2>0)//向上更新,父亲存在的时候
    {
        k=k/2;//父亲结点
        dat[k]=max(dat[2*k],dat[2*k+1]);//父亲结点为左右孩子的较大值
    }
}
int Query(int a,int b,int k,int l,int r)//闭区间
{
    if(r<a||b<l) return 0;
    if(a<=l&&r<=b) return dat[k];
    else
    {
        int v1=Query(a,b,k*2,l,(l+r)/2);
        int v2=Query(a,b,k*2+1,(l+r)/2+1,r);
        return max(v1,v2);
    }
}
int main()
{
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        Init();
        for(int i=1; i<=N; ++i)
        {
            int t;
            scanf("%d",&t);
            update(t,i);
        }
        while(M--)
        {
            char str[5];
            int a,b;
            scanf("%s%d%d",str,&a,&b);
            if(str[0]=='Q')
            printf("%d\n",Query(a,b,1,1,mxn));
            else update(b,a);
        }
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值