洛谷 P4513 小白逛公園 【線段——單點修改,求最大連續字段和】

主要就是維護ls,rs,ms,s

通過dp(只有一點點)維護最大連續字段和

直接上代碼

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=500005;
struct tr
{
    int l,r,s,ls,rs,ms;
}tree[maxn*4];
int a[maxn],n,m;
void update(int now)
{
    tree[now].s=tree[now<<1].s+tree[now<<1|1].s;
    tree[now].ls=max(tree[now<<1].ls,tree[now<<1].s+tree[now<<1|1].ls);
    tree[now].rs=max(tree[now<<1|1].rs,tree[now<<1|1].s+tree[now<<1].rs);
    tree[now].ms=max(max(max(tree[now<<1].ls,tree[now<<1|1].rs),tree[now<<1].rs+tree[now<<1|1].ls),max(tree[now<<1].ms,tree[now<<1|1].ms));
}
void build(int l , int r , int now)
{
    tree[now].l=l; tree[now].r=r;
    if(l==r)
    {
        tree[now].s=a[l];
        tree[now].ls=a[l];
        tree[now].rs=a[l];
        tree[now].ms=a[l];
    }
    else
    {
        int mid=(l+r)>>1;
        build(l,mid,now<<1);
        build(mid+1,r,now<<1|1);
        update(now);
    }
}
tr query(int l ,int r ,int now)
{
    if(tree[now].l==l && tree[now].r==r)
        return tree[now];
    int mid=(tree[now].l+tree[now].r)>>1;
    if(mid>=r)
        return query(l,r,now<<1);
    if(mid<l)
        return query(l,r,now<<1|1);
    tr ll=query(l,mid,now<<1);
    tr rr=query(mid+1,r,now<<1|1);
    tr yy;
    yy.s=ll.s+rr.s;
    yy.ls=max(ll.ls,ll.s+rr.ls);
    yy.rs=max(rr.rs,rr.s+ll.rs);
    yy.ms=max(max(max(ll.ls,rr.rs),ll.rs+rr.ls),max(ll.ms,rr.ms));
    return yy;
}
void change(int l ,int r ,int k ,int x ,int now)
{
    if(l==r && l==k)
    {
        tree[now].ls=tree[now].rs=tree[now].ms=tree[now].s=x;
        return;
    }
    int mid=(l+r)>>1;
    if(k<=mid)
    {
        change(l,mid,k,x,now<<1);
        update(now);
    }
    else
    {
        change(mid+1,r,k,x,now<<1|1);
        update(now);
    }
}
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);    
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        int q;
        scanf("%d",&q);
        if(q==1)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a>b)
                printf("%d\n",query(b,a,1).ms);
            else
                printf("%d\n",query(a,b,1).ms);
        }
        else
        {
            int a,b;
            scanf("%d%d",&a,&b);
            change(1,n,a,b,1);
        }
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章