HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值)

HDOJ(HDU).1754 I Hate It (ST 单点替换 区间最大值)

点我挑战题目

题意分析

从题目中可以看出是大数据的输入,和大量询问。基本操作有:
1.Q(i,j)代表求区间max(a[k]) k∈[i,j];
2.U(i,j)代表a[i] = j;

对于询问U,用单点替换的操作维护线段树。对于询问Q,那么除了叶子节点,其他的节点应该保存的是左子树和右子树的最大值,因此pushup函数应该是对最大值的一个维护,query的时候找出的应该是最大值,故改为ans = max(……) 即可。

代码总览

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define nmax 200005
using namespace std;
int a[nmax],add[nmax<<2],sum[nmax<<2];
void pushup(int rt)
{
    sum[rt] = max(sum[rt<<1] ,sum[rt<<1|1]);
}
void pushdown(int rt, int ln, int rn)
{
    if(add[rt]){
        add[rt<<1]+=add[rt];
        add[rt<<1|1]+=add[rt];
        sum[rt<<1]+=add[rt]*ln;
        sum[rt<<1|1]+=add[rt]*rn;
        add[rt] = 0;
    }

}
void build(int l ,int r, int rt)
{
    if(l == r){
        sum[rt] = a[l];
        return;
    }
    int m = (l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    pushup(rt);
}
void updatep(int L, int c, int l, int r, int rt)
{
    if(l == r){
        sum[rt] = c;
        return;
    }
    int m = (l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    if(L<=m) updatep(L,c,l,m,rt<<1);
    else updatep(L,c,m+1,r,rt<<1|1);
    pushup(rt);
}
void updatei(int L, int R, int c, int l, int r, int rt)
{
    if( l>=L && r<= R){
        sum[rt]+=c*(r-l+1);
        add[rt]+=c;
        return;
    }
    int m = (l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    if(L<=m) updatei(L,R,c,l,m,rt<<1);
    if(R>m) updatei(L,R,c,m+1,r,rt<<1);
    pushup(rt);
}
int query(int L, int R, int l ,int r, int rt)
{
    if(L<=l && r<=R){
        return sum[rt];
    }
    int m = (l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    int ANS =0;
    if(L<=m) ANS = max( query(L,R,l,m,rt<<1),ANS);
    if(R>m) ANS = max(query(L,R,m+1,r,rt<<1|1),ANS);
    return ANS;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n,m;
    while(scanf("%d%d",&n,&m)!= EOF){
        for(int i =1;i<=n; ++i) scanf("%d",&a[i]);
        build(1,n,1);
        char com;
        for(int i = 1;i<=m;++i){
            scanf(" %c",&com);
            if(com == 'Q'){
                int L,R;
                scanf("%d%d",&L,&R);
                printf("%d
",query(L,R,1,n,1));
            }else{
                int L,c;
                scanf("%d%d",&L,&c);
                updatep(L,c,1,n,1);
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/pengwill/p/7367138.html