支持单点修改,维护最大子段和的线段树 补发一波

原题luogu

其实难就难在如何合并区间信息(但是我记得有学长讲过)

l(tr)表示包含左端点的最大子段和,r(tr)表示包含右端点的最大子段和,mx(tr)表示该区间的最大子段和,sum(tr)表示该区间的总和

ls表示左儿子,rs表示右儿子

inline void upd(int tr) {
    l(tr)=max(l(ls),sum(ls)+l(rs));
    mx(tr)=max(max(mx(ls),mx(rs)),r(ls)+l(rs));
    r(tr)=max(r(rs),sum(rs)+r(ls));
    sum(tr)=sum(ls)+sum(rs);
}

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#define ll long long
#define R register ll
#define ls (tr<<1)
#define rs (tr<<1|1)
using namespace std;
struct node{
    ll mxl,mx,mxr,sum;
    #define l(i) t[i].mxl
    #define mx(i) t[i].mx
    #define r(i) t[i].mxr
    #define sum(i) t[i].sum
}t[2000010];
int n,m;
inline ll g() {
    R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
    do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
}
inline void upd(int tr) {
    l(tr)=max(l(ls),sum(ls)+l(rs));
    mx(tr)=max(max(mx(ls),mx(rs)),r(ls)+l(rs));
    r(tr)=max(r(rs),sum(rs)+r(ls));
    sum(tr)=sum(ls)+sum(rs);
}
inline void build(int tr,ll l,ll r) {
    if(l==r) {l(tr)=mx(tr)=r(tr)=sum(tr)=g(); return ;}
    R md=(l+r)>>1;
    build(ls,l,md),build(rs,md+1,r);
    upd(tr);
}
inline void inc(int tr,ll l,ll r,ll pos,ll d) {
    if(l==r) {mx(tr)=l(tr)=r(tr)=sum(tr)=d; return ;}
    R md=(l+r)>>1;
    if(pos>md) inc(rs,md+1,r,pos,d);
    else inc(ls,l,md,pos,d);
    upd(tr);
}
inline node query(int tr,ll l,ll r,ll LL,ll RR) {
    if(l==LL&&r==RR) return t[tr];
    R md=(l+r)>>1;
    if(LL>md) return query(rs,md+1,r,LL,RR);
    else if(RR<md+1) return query(ls,l,md,LL,RR);
    register node x=query(ls,l,md,LL,md),y=query(rs,md+1,r,md+1,RR),ret;
    ret.mxl=max(x.mxl,x.sum+y.mxl); ret.mxr=max(y.mxr,x.mxr+y.sum);
    ret.mx=max(max(x.mx,y.mx),x.mxr+y.mxl); ret.sum=x.sum+y.sum;
    return ret;
}
signed main() {
    n=g(),m=g();
    memset(t,0xcf,sizeof(t));
    build(1,1,n);
    for(R i=1;i<=m;++i) {
        R k=g(),l=g(),r=g(); 
        if(k&1) {
            if(r<l) swap(l,r);
            printf("%lld\n",query(1,1,n,l,r).mx);
        } else inc(1,1,n,l,r);
    }
}

2019.04.09

 

posted @ 2019-04-09 23:59  LuitaryiJack  阅读(237)  评论(2编辑  收藏  举报