JDOJ-1260: VIJOS-P1083 小白逛公园

[文章目录]

Description

路的一边从南到北依次排着n个公园,小白早就看花了眼,自己也不清楚该去哪些公园玩了。一开始,小白就根据公园的风景给每个公园打了分。小新为了省事,每次遛狗的时候都会事先规定一个范围,小白只可以选择第a个和第b个公园之间(包括a、b两个公园)选择连续的一些公园玩。小白当然希望选出的公园的分数总和尽量高咯。同时,由于一些公园的景观会有所改变,所以,小白的打分也可能会有一些变化。 那么,就请你来帮小白选择公园吧。

线段树单点修改,区间查询最大连续子序列和,每个区间维护三个参数,Mx[]是区间最大连续子段和,Mxl[]是必包含最左端断点的最大连续子段和,Mxr[]是必包含最右端最大连续子段和。

然后在维护Mxl、Mxr的时候需要维护一个sum[],所以总共4个参。通过是否跨mid进行比较就好了。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 2001000
#define lson pos<<1
#define rson pos<<1|1
using namespace std;
int n,m,sw,k2,k1;
int val[501000];
int sum[N],Mx[N],Mxl[N],Mxr[N];
void build(int pos,int l,int r)
{
    if(l==r)
    {
        sum[pos]=Mx[pos]=Mxl[pos]=Mxr[pos]=val[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(lson,l,mid);
    build(rson,mid+1,r);
    sum[pos]=sum[lson]+sum[rson];
    Mx[pos]=max(Mxr[lson]+Mxl[rson],max(Mx[lson],Mx[rson]) );
    Mxl[pos]=max(Mxl[lson],sum[lson]+Mxl[rson]);
    Mxr[pos]=max(Mxr[rson],sum[rson]+Mxr[lson]);
}
int get_left(int pos,int l,int r,int x,int y)
{
    if(x<=l&&y>=r)
        return Mxl[pos];
    int mid=(l+r)>>1;
    if(y<=mid)
        return get_left(lson,l,mid,x,y);
    if(x>mid)
        return get_left(rson,mid+1,r,x,y);
    return max(get_left(lson,l,mid,x,y),sum[lson]+get_left(rson,mid+1,r,x,y) );
}
int get_right(int pos,int l,int r,int x,int y)
{
    if(x<=l&&y>=r)
        return Mxr[pos];
    int mid=(l+r)>>1;
    if(y<=mid)
        return get_right(lson,l,mid,x,y);
    if(x>mid)
        return get_right(rson,mid+1,r,x,y);
    return max(get_right(rson,mid+1,r,x,y),sum[rson]+get_right(lson,l,mid,x,y) );
}
int query(int pos,int l,int r,int x,int y)
{
    if(x<=l&&y>=r)
        return Mx[pos];
    int mid=(l+r)>>1;
    if(y<=mid)
        return query(lson,l,mid,x,y);
    else if(x>mid)
        return query(rson,mid+1,r,x,y);
    else
        return max( query(lson,l,mid,x,y),max(query(rson,mid+1,r,x,y),get_right(lson,l,mid,x,y)+get_left(rson,mid+1,r,x,y) ) );
}
void updata(int pos,int l,int r,int x,int y)
{
    if(l==x&&r==x)
    {
        sum[pos]=Mx[pos]=Mxl[pos]=Mxr[pos]=y;
        return ;
    }
    int mid=(l+r)>>1;
    if(x<=mid)
        updata(lson,l,mid,x,y);
    else if(x>mid)
        updata(rson,mid+1,r,x,y);
    sum[pos]=sum[lson]+sum[rson];
    Mx[pos]=max(Mxr[lson]+Mxl[rson],max(Mx[lson],Mx[rson]) );
    Mxl[pos]=max(Mxl[lson],sum[lson]+Mxl[rson]);
    Mxr[pos]=max(Mxr[rson],sum[rson]+Mxr[lson]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
    build(1,1,n);
    while(m--)
    {
        scanf("%d%d%d",&sw,&k1,&k2);
        if(sw==1)
        {
            if(k1>k2)
                swap(k1,k2);
            printf("%d\n",query(1,1,n,k1,k2));
        }
        else
            updata(1,1,n,k1,k2);
    }
    return 0;
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注