[线段树] P4513 小白逛公园

题意:
序列,单点修改,询问区间最大子段和
最大子段和指的是找出一个可以是空的子区间,和最大

著名的新手杀手题。。。
其实也不难
对于每个区间,维护一个最大前缀,最大后缀,以及区间内部的答案
每次合并的时候,即答案选取左子区间的max,右子区间的max,或者左子区间的最大后缀+右子区间的最大前缀

P4513

\(\\\)
\(\\\)
\(\\\)
\(\\\)
\(\\\)

#include<bits/stdc++.h>
#define int long long
#define mid ((s+t)>>1)
#define ls (p<<1)
#define rs (ls+1)
using namespace std;

const int Max=5e5+10;

int n,m;
int a[Max];


struct node
{
    int res,sum,lm,rm;
}d[Max*4];
 

void pushup(int p)
{
    d[p].sum=d[ls].sum+d[rs].sum;
    d[p].res=max(d[ls].rm+d[rs].lm,max(d[rs].res,d[ls].res));
    if(d[rs].lm>d[ls].lm-d[ls].sum) d[p].lm=d[ls].sum+d[rs].lm;
    else d[p].lm=d[ls].lm;
    if(d[ls].rm>d[rs].rm-d[rs].sum) d[p].rm=d[rs].sum+d[ls].rm;
    else d[p].rm=d[rs].rm;
}

void build(int p,int s,int t)
{
    if(s==t) 
    {
        d[p].sum=a[s];
        d[p].lm=a[s];
        d[p].rm=a[s];
        d[p].res=a[s];
        return;
    }
    build(ls,s,mid);
    build(rs,mid+1,t);
    pushup(p);
}

void update(int p,int s,int t,int x,int c)
{
    if(s==t)
    {
        d[p].sum=c;
        d[p].res=c;
        d[p].lm=c;
        d[p].rm=c;
        return;
    }
    if(x<=mid) update(ls,s,mid,x,c);
    else update(rs,mid+1,t,x,c);
    pushup(p);
}

node query(int p,int l,int r,int s,int t)
{
    if(l<=s&&r>=t)
    {
        return d[p];
    }
    if(r<=mid) return query(ls,l,r,s,mid);
    else if(l>mid) return query(rs,l,r,mid+1,t);
    else
    {
        auto x=query(ls,l,r,s,mid),y=query(rs,l,r,mid+1,t);
        node ans;
        ans.sum=x.sum+y.sum;
        ans.res=max(x.rm+y.lm,max(x.res,y.res));
        if(y.lm>x.lm-x.sum) ans.lm=x.sum+y.lm;
        else ans.lm=x.lm;
        if(x.rm>y.rm-y.sum) ans.rm=y.sum+x.rm;
        else ans.rm=y.rm;
        return ans;
    }
}

signed main()
{
    ios::sync_with_stdio(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    build(1,1,n);
    for(int i=1;i<=m;i++)
    {
        int x,y,z;
        cin>>x>>y>>z;
        if(x==1)
        {
            if(z<y) swap(z,y);
            cout<<query(1,y,z,1,n).res<<"\n";
        }
        else
        {
            update(1,1,n,y,z);
        }
    }
    return 0;
}
posted @ 2022-02-19 23:21  juuich  阅读(24)  评论(0编辑  收藏  举报