Bootstrap

bzoj5144 [Ynoi2018]末日时在做什么?有没有空?可以来拯救吗?

这个死宅题面就不吐槽了。。。

2018目标:一定要让 nzhtl1477 n z h t l 1477 把罚抄打通!

这题当然是 O(nn+nlogn) O ( n n + n l o g n )

先考虑全局最大子段和,全局加 O(nlogn) O ( n l o g n ) 怎么做。
考虑线段树,显然,如果我们每个区间维护一个答案函数 f(x) f ( x ) 表示加 x x 时答案是多少,这题就做完了。
维护最大子段和,显然要维护三个函数:pre(x),suf(x),ans(x)

pre(x),suf(x) p r e ( x ) , s u f ( x ) 可以半平面交,由于斜率大于 0 0 ,所以可以拿栈实现
ans(x)除了由两个儿子的 ans(x) a n s ( x ) 合并而来,还可以用左儿子的 suf s u f ,右儿子的 pre p r e 合并。可以考虑维护双指针指向两个下凸壳,这样单调扫一遍与 ans a n s 合并就行

回到原题,可以考虑分块,每块维护个线段树。

修改:对于中间的块,记 3 3 个指针指向三个分段函数,表示现在在哪一段,然后暴力ptr++。两边零散的块暴力在线段树上修改经过的区间。这样修改的长度之和是 O(n) O ( n ) 的,因为每层常数个区间被修改。然后指针清零,这样每次只会增加 O(n) O ( n ) 次指针增加机会,所以指针增加次数还是 O(nn) O ( n n )

询问:两边零散的块暴力, O(n) O ( n ) 。中间的块:
1. 1. 答案在块里,用指针 O(1) O ( 1 ) 得到结果
2. 2. 答案跨越块。记一个 maxsuf maxsuf ,每次更新与计算是 O(1) O ( 1 ) 的。记得 maxsuf=max(maxsuf,0) maxsuf=max(maxsuf,0)

然后复杂度就是 O(nn) O ( n n )

然而下列代码是被卡常的:(正确性倒是保证了)

#include<bits/stdc++.h>

#define BLK 520
#define maxn 100100
#define xx first
#define yy second
#define LK(x) ((x)*kuai)
#define RK(x) min((x+1)*kuai,n)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> par;
par mem[maxn*80],*ptr=mem,tmp1[maxn<<2],tmp2[maxn<<2],sta[maxn<<2],lxldl;
// AxB<CxD judge!
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

inline int rd(){
    char ch=nc();
    register int sum=0,f=0;
    while(!(ch>='0'&&ch<='9')&&ch!='-')ch=nc();
    if(ch=='-')f=1,ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return f?-sum:sum;
}

inline ll max(const ll& a,const ll& b){
    return a<b?b:a;
}
inline int jdg(par A,par B,par C,par D){
    ll a=(A.yy-B.yy)*(D.xx-C.xx);
    ll b=(C.yy-D.yy)*(B.xx-A.xx);
    return a==b?0:(a<b?-1:1);
}
inline ll cal(par A,ll x){
    return A.xx*x+A.yy;
} 
par inline  _sum(par a,par b){
    return par(a.xx+b.xx,a.yy+b.yy);
}
bool inline cmp(par a,par b){
    return a.xx<b.xx||(a.xx==b.xx&&a.yy>b.yy);
}
struct WXHGGG{
    par *a;
    int size;
    void inline cp(par* bg,par* ed){size=ed-bg,memcpy(a,bg,sizeof(par)*size);}
    void inline cp(par* bg,int& sz){sz=size,memcpy(bg,a,sizeof(par)*size);}
    void inline rewrite(ll atg){
        int p;
        for(p=0;p+1<size&&cal(a[p],atg)<cal(a[p+1],atg);)p++;
        for(int i=p;i<size;++i)a[i].yy+=a[i].xx*atg,a[i-p]=a[i];
        size-=p;
    }
    void print(){
        printf("\n{size=%d}",size);
        for(int i=0;i<size;++i)printf("[%lld,%lld]",a[i].xx,a[i].yy);
        puts("");
    }
};
void inline LXLDuliu(int& tp,par lxldl){
    if(tp&&lxldl.xx==sta[tp-1].xx){
        sta[tp-1].yy=max(sta[tp-1].yy,lxldl.yy);
        return ;
    }
    while(tp>1&&jdg(sta[tp-2],sta[tp-1],sta[tp-1],lxldl)>=0)tp--;
    sta[tp++]=lxldl;
}
#pragma pack(1)
struct WXHTBQ{
    WXHGGG pre[1025],suf[1025],ans[1025];
    ll sum[1025],a[BLK],atg[1025],alltg;
    int n,len[1025],pans,ppre,psuf;
    void upd(int o){
        int tp=0,ls=o<<1,rs=o<<1|1;

        //merge pre
        pre[ls].cp(sta,tp);
        for(int i=0;i<pre[rs].size;++i){
            lxldl=par(len[ls]+pre[rs].a[i].xx,sum[ls]+pre[rs].a[i].yy);
            LXLDuliu(tp,lxldl);
        }
        pre[o].cp(sta,sta+tp),tp=0;

        //merge suf
        suf[rs].cp(sta,tp);
        for(int i=0;i<suf[ls].size;++i){
            lxldl=par(len[rs]+suf[ls].a[i].xx,sum[rs]+suf[ls].a[i].yy);
            LXLDuliu(tp,lxldl);
        }
        suf[o].cp(sta,sta+tp);

        int tp1=0,tp2=0;
        //merge ans
        for(int lxl,dl=0,i=0,j=0;i<suf[ls].size-1||j<pre[rs].size-1;){
            tmp1[tp1++]=_sum(suf[ls].a[i],pre[rs].a[j]);
            if(i==suf[ls].size-1)j++;
            else if(j==pre[rs].size-1)i++;
            else lxl=jdg(suf[ls].a[i],suf[ls].a[i+1],pre[rs].a[j],pre[rs].a[j+1]),i+=(lxl<=dl),j+=(lxl>=dl);
        }

        tmp1[tp1++]=_sum(suf[ls].a[suf[ls].size-1],pre[rs].a[pre[rs].size-1]);
        for(int lxl,dl=0,i=0,j=0;i<ans[ls].size||j<ans[rs].size;){
            if(i==ans[ls].size)tmp2[tp2++]=ans[rs].a[j++];
            else if(j==ans[rs].size)tmp2[tp2++]=ans[ls].a[i++];
            else if(cmp(ans[ls].a[i],ans[rs].a[j]))tmp2[tp2++]=ans[ls].a[i++];
            else tmp2[tp2++]=ans[rs].a[j++];
        }
        tp=0;
        for(int lxl,dl=0,i=0,j=0;i<tp1||j<tp2;){
            if(i==tp1)lxldl=tmp2[j++];
            else if(j==tp2)lxldl=tmp1[i++];
            else if(cmp(tmp1[i],tmp2[j]))lxldl=tmp1[i++];
            else lxldl=tmp2[j++];
            LXLDuliu(tp,lxldl);
        }
        ans[o].cp(sta,sta+tp);
        sum[o]=sum[o<<1]+sum[o<<1|1];
    }
    void build(int o,int l,int r){
        pre[o].a=ptr,ptr+=r-l+1;
        suf[o].a=ptr,ptr+=r-l+1;
        pre[o].size=suf[o].size=ans[o].size=0;
        ans[o].a=ptr,ptr+=r-l+1;
        len[o]=r-l+1;
        if(l==r){
            sum[o]=a[l];
            pre[o].a[0]=suf[o].a[0]=par(1,a[l]);
            ans[o].a[0]=par(1,a[l]);
            pre[o].size=suf[o].size=ans[o].size=1;
            return ;
        }
        int mid=l+r>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
        upd(o);
    }
    void rewrite(int o,ll A){
        pre[o].rewrite(A);
        suf[o].rewrite(A);
        ans[o].rewrite(A);
    }
    void mdy(int o,int l,int r,int ql,int qr,ll A){
        if(ql<=l&&r<=qr){
            rewrite(o,A);
            sum[o]+=A*len[o],atg[o]+=A;
            return ;
        }
        int mid=l+r>>1;
        if(atg[o]){
            atg[o<<1]+=atg[o],sum[o<<1]+=len[o<<1]*atg[o];
            atg[o<<1|1]+=atg[o],sum[o<<1|1]+=len[o<<1|1]*atg[o];
            rewrite(o<<1,atg[o]),rewrite(o<<1|1,atg[o]);    
        }
        if(ql<=mid)mdy(o<<1,l,mid,ql,qr,A);
        if(qr>mid)mdy(o<<1|1,mid+1,r,ql,qr,A);
        atg[o]=0,upd(o);
    }

    void shift(ll tg){
        atg[1]+=tg,alltg+=tg,sum[1]+=len[1]*tg;
        while(pans+1<ans[1].size&&cal(ans[1].a[pans],alltg)<cal(ans[1].a[pans+1],alltg))pans++;
        while(ppre+1<pre[1].size&&cal(pre[1].a[ppre],alltg)<cal(pre[1].a[ppre+1],alltg))ppre++;
        while(psuf+1<suf[1].size&&cal(suf[1].a[psuf],alltg)<cal(suf[1].a[psuf+1],alltg))psuf++;
    }
    void init(ll* bg,ll* ed){
        n=ed-bg;
        for(int i=0;i<n;++i)a[i]=bg[i];
        build(1,0,n-1);     
    }
    void pd(ll* a){
        pans=ppre=psuf=0;
        for(int i=0;i<n;++i)a[i]+=alltg;
        rewrite(1,alltg);
        alltg=0;
    }
    #define ANS 1
    #define PRE 2
    #define SUF 3
    ll kagari(ll* a,ll* b,int FLAG){
        ll mn=0,nw=0,ans=0;
        if(FLAG==ANS)for(int i=0;i<b-a;++i)
            nw+=a[i]+alltg,mn=min(mn,nw),ans=max(ans,nw-mn);
        else if(FLAG==PRE)for(int i=0;i<b-a;++i)
            nw+=a[i]+alltg,ans=max(ans,nw);
        else for(int i=b-a-1;i>=0;--i)
            nw+=a[i]+alltg,ans=max(ans,nw);
        return ans;
    }
}s[BLK];
int kuai,n,m;
ll a[maxn];
int main(){
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    n=rd(),m=rd();
    for(int i=0;i<n;++i)a[i]=rd();
    kuai=450;
    int _m=(n+kuai-1)/kuai;
    for(int i=0;i<_m;++i)s[i].init(a+LK(i),a+RK(i)),s[i].shift(0);
    for(int i=0,op,l,r,x;i<m;++i){
        op=rd(),l=rd(),r=rd();
        l--,r--;
        if(op==1){
            x=rd();
            int bl=l/kuai,br=r/kuai;
            if(bl==br){
                s[bl].pd(a+LK(bl));
                for(int i=l;i<=r;++i)a[i]+=x;
                s[bl].mdy(1,0,s[bl].n-1,l%kuai,r%kuai,x);
                s[bl].shift(0);
            } else {
                if(l==LK(bl))s[bl].shift(x);
                else {
                    s[bl].pd(a+LK(bl));
                    for(int i=l;i<RK(bl);++i)a[i]+=x;
                    s[bl].mdy(1,0,s[bl].n-1,l%kuai,s[bl].n-1,x);
                    s[bl].shift(0); 
                }
                if(r==RK(br)-1)s[br].shift(x);
                else {
                    s[br].pd(a+LK(br));
                    for(int i=LK(br);i<=r;++i)a[i]+=x;
                    s[br].mdy(1,0,s[br].n-1,0,r%kuai,x);
                    s[br].shift(0);
                }
                for(int j=bl+1;j<br;++j)s[j].shift(x);
            }
        } else {
            int bl=l/kuai,br=r/kuai;
            if(bl==br){
                printf("%lld\n",max(0ll,s[bl].kagari(a+l,a+r+1,ANS)));
            } else {
                ll ans=max(s[bl].kagari(a+l,a+RK(bl),ANS),s[br].kagari(a+LK(br),a+r+1,ANS));
                ll sum=s[bl].kagari(a+l,a+RK(bl),SUF);
                for(int i=bl+1;i<br;++i)
                    ans=max(ans,cal(s[i].pre[1].a[s[i].ppre],s[i].alltg)+sum),
                    ans=max(ans,cal(s[i].ans[1].a[s[i].pans],s[i].alltg)),
                    sum+=s[i].sum[1],sum=max(sum,cal(s[i].suf[1].a[s[i].psuf],s[i].alltg)),
                    sum=max(sum,0ll);
                ans=max(ans,sum+s[br].kagari(a+LK(br),a+r+1,PRE));
                printf("%lld\n",max(0ll,ans));
            }
        }
    }
} 

UPD:卡常大成功!秘诀:将线段树根节点的内存分配在一起,rewrite次数可以优化,merge ans的时候可以先把两边压到栈里再归并

实际上前2个最有用,因为BZOJ老爷机内存访问巨慢。。。

#include<bits/stdc++.h>
#define BLK 460
#define maxn 100100
#define xx first
#define yy second
#define LK(x) ((x)*kuai)
#define RK(x) min((x+1)*kuai,n)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> par;
char outbuf[1<<24],*O=outbuf;
par mem[maxn*70],*ptr=mem,*nptr=mem,tmp1[maxn<<2],tmp2[maxn<<2],tmp3[maxn<<2],sta[maxn<<2],lxldl;
// AxB<CxD judge!
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

inline int rd(){
    register int sum=0,f=0;
//    scanf("%d",&sum);
//    return sum;
    char ch=nc();
    while(!(ch>='0'&&ch<='9')&&ch!='-')ch=nc();
    if(ch=='-')f=1,ch=nc();
    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
    return f?-sum:sum;
}
void print(ll x){
    if(!x)*O++='0';
    static char s[100],*t=s;
    ll y=0;
    while(x)y=x/10,*t++=x-10*y+'0',x=y;
    while(t!=s)*O++=*--t;
    *O++='\n';
}
inline ll max(const ll& a,const ll& b){
    return a<b?b:a;
}
inline int jdg(par A,par B,par C,par D){
    ll a=(A.yy-B.yy)*(D.xx-C.xx);
    ll b=(C.yy-D.yy)*(B.xx-A.xx);
    return a==b?0:(a<b?-1:1);
}
inline ll cal(par A,ll x){
    return A.xx*x+A.yy;
} 
par inline  _sum(par a,par b){
    return par(a.xx+b.xx,a.yy+b.yy);
}
bool inline cmp(par a,par b){
    return a.xx<b.xx||(a.xx==b.xx&&a.yy>b.yy);
}
struct WXHGGG{
    par *a;
    int size;
    void cp(par* bg,par* ed){size=ed-bg,memcpy(a,bg,sizeof(par)*size);}
    void cp(par* bg,int& sz){sz=size,memcpy(bg,a,sizeof(par)*size);}
    void rewrite(ll atg){
        int p;
        for(p=0;p+1<size&&cal(a[p],atg)<cal(a[p+1],atg);)p++;
        for(int i=p;i<size;++i)a[i].yy+=a[i].xx*atg,a[i-p]=a[i];
        size-=p;
    }
    void print(){
        printf("\n{size=%d}",size);
        for(int i=0;i<size;++i)printf("[%lld,%lld]",a[i].xx,a[i].yy);
        puts("");
    }
};
void inline LXLDuliu(int& tp,par lxldl,par* sta=::sta){
    if(tp&&lxldl.xx==sta[tp-1].xx){
        sta[tp-1].yy=max(sta[tp-1].yy,lxldl.yy);
        return ;
    }
    while(tp>1&&jdg(sta[tp-2],sta[tp-1],sta[tp-1],lxldl)>=0)tp--;
    sta[tp++]=lxldl;
}
struct WXHTBQ{
    WXHGGG pre[BLK<<2],suf[BLK<<2],ans[BLK<<2];
    ll a[BLK],sum[BLK<<2],atg[BLK<<2],alltg,_pans,_ppre,_psuf;
    int n,len[BLK<<2],pans,ppre,psuf;
    void upd(int o){
        int tp=0,ls=o<<1,rs=o<<1|1;

        //merge pre
        pre[ls].cp(sta,tp);
        for(int i=0;i<pre[rs].size;++i){
            lxldl=par(len[ls]+pre[rs].a[i].xx,sum[ls]+pre[rs].a[i].yy);
            LXLDuliu(tp,lxldl);
        }
        pre[o].cp(sta,sta+tp),tp=0;

        //merge suf
        suf[rs].cp(sta,tp);
        for(int i=0;i<suf[ls].size;++i){
            lxldl=par(len[rs]+suf[ls].a[i].xx,sum[rs]+suf[ls].a[i].yy);
            LXLDuliu(tp,lxldl);
        }
        suf[o].cp(sta,sta+tp);

        int tp1=0,tp2=0;
        //merge ans
        for(int lxl,dl=0,i=0,j=0;i<suf[ls].size-1||j<pre[rs].size-1;){
            tmp1[tp1++]=_sum(suf[ls].a[i],pre[rs].a[j]);
            if(i==suf[ls].size-1)j++;
            else if(j==pre[rs].size-1)i++;
            else lxl=jdg(suf[ls].a[i],suf[ls].a[i+1],pre[rs].a[j],pre[rs].a[j+1]),i+=(lxl<=dl),j+=(lxl>=dl);
        }

        tmp1[tp1++]=_sum(suf[ls].a[suf[ls].size-1],pre[rs].a[pre[rs].size-1]);
        for(int lxl,dl=0,i=0,j=0;i<ans[ls].size||j<ans[rs].size;){
            if(i==ans[ls].size)lxldl=ans[rs].a[j++];
            else if(j==ans[rs].size)lxldl=ans[ls].a[i++];
            else if(cmp(ans[ls].a[i],ans[rs].a[j]))lxldl=ans[ls].a[i++];
            else lxldl=ans[rs].a[j++];
            LXLDuliu(tp2,lxldl,tmp2);
        }
        tp=0;
        for(int lxl,dl=0,i=0,j=0;i<tp1||j<tp2;){
            if(i==tp1)lxldl=tmp2[j++];
            else if(j==tp2)lxldl=tmp1[i++];
            else if(cmp(tmp1[i],tmp2[j]))lxldl=tmp1[i++];
            else lxldl=tmp2[j++];
            LXLDuliu(tp,lxldl);
        }
        ans[o].cp(sta,sta+tp);
        sum[o]=sum[o<<1]+sum[o<<1|1];
    }
    void build(int o,int l,int r){
        if(o>1){
            pre[o].a=ptr,ptr+=r-l+1;
            suf[o].a=ptr,ptr+=r-l+1;
            ans[o].a=ptr,ptr+=r-l+1;    
        } else {
            pre[o].a=nptr,nptr+=r-l+1;
            suf[o].a=nptr,nptr+=r-l+1;
            ans[o].a=nptr,nptr+=r-l+1;
        }
        pre[o].size=suf[o].size=ans[o].size=0;
        len[o]=r-l+1;
        if(l==r){
            sum[o]=a[l];
            pre[o].a[0]=suf[o].a[0]=par(1,a[l]);
            ans[o].a[0]=par(1,a[l]);
            pre[o].size=suf[o].size=ans[o].size=1;
            return ;
        }
        int mid=l+r>>1;
        build(o<<1,l,mid);
        build(o<<1|1,mid+1,r);
        upd(o);
    }
    void rewrite(int o,ll A){
        pre[o].rewrite(A);
        suf[o].rewrite(A);
        ans[o].rewrite(A);
    }
    void mdy(int o,int l,int r,int ql,int qr,ll A,ll tg=0){
        if(ql<=l&&r<=qr){
            rewrite(o,A+tg);
            sum[o]+=A*len[o],atg[o]+=A;
            return ;
        }
        int mid=l+r>>1;
        if(atg[o]){
            atg[o<<1]+=atg[o],sum[o<<1]+=len[o<<1]*atg[o];
            atg[o<<1|1]+=atg[o],sum[o<<1|1]+=len[o<<1|1]*atg[o];
            if(ql>mid)rewrite(o<<1,atg[o]);
            if(qr<=mid)rewrite(o<<1|1,atg[o]);  
        }
        if(ql<=mid)mdy(o<<1,l,mid,ql,qr,A,atg[o]);
        if(qr>mid)mdy(o<<1|1,mid+1,r,ql,qr,A,atg[o]);
        atg[o]=0,upd(o);
    }

    void shift(ll tg){
        atg[1]+=tg,alltg+=tg,sum[1]+=len[1]*tg;
        while(pans+1<ans[1].size&&cal(ans[1].a[pans],alltg)<cal(ans[1].a[pans+1],alltg))pans++;
        while(ppre+1<pre[1].size&&cal(pre[1].a[ppre],alltg)<cal(pre[1].a[ppre+1],alltg))ppre++;
        while(psuf+1<suf[1].size&&cal(suf[1].a[psuf],alltg)<cal(suf[1].a[psuf+1],alltg))psuf++;
        _pans=cal(ans[1].a[pans],alltg);
        _ppre=cal(pre[1].a[ppre],alltg);
        _psuf=cal(suf[1].a[psuf],alltg);
    }
    void init(ll* bg,ll* ed){
        n=ed-bg;
        for(int i=0;i<n;++i)a[i]=bg[i];
        build(1,0,n-1);     
    }
    void pd(ll* a){
        pans=ppre=psuf=0;
        for(int i=0;i<n;++i)a[i]+=alltg;
        rewrite(1,alltg);
        alltg=0;
    }
    #define ANS 1
    #define PRE 2
    #define SUF 3
    ll kagari(ll* a,ll* b,int FLAG){
        ll mn=0,nw=0,ans=0;
        if(FLAG==ANS)for(int i=0;i<b-a;++i)
            nw+=a[i]+alltg,mn=min(mn,nw),ans=max(ans,nw-mn);
        else if(FLAG==PRE)for(int i=0;i<b-a;++i)
            nw+=a[i]+alltg,ans=max(ans,nw);
        else for(int i=b-a-1;i>=0;--i)
            nw+=a[i]+alltg,ans=max(ans,nw);
        return ans;
    }
}s[BLK];
int kuai,n,m;
ll a[maxn];

inline int rd2(){
    char ch=nc();
    while(!(ch>='A'&&ch<='Z'))ch=nc();
    return ch=='A'?1:2;
}
int main(){
//  freopen("in.txt","r",stdin);
//  freopen("out.txt","w",stdout);
    n=rd(),m=rd();
    for(int i=0;i<n;++i)a[i]=rd();
    kuai=450;
    ptr+=3*n;
    int _m=(n+kuai-1)/kuai;
    for(int i=0;i<_m;++i)s[i].init(a+LK(i),a+RK(i)),s[i].shift(0);
    for(int i=0,op,l,r,x;i<m;++i){
        op=rd(),l=rd(),r=rd();
        l--,r--;
        if(op==1){
            x=rd();
            int bl=l/kuai,br=r/kuai;
            if(bl==br){
                s[bl].pd(a+LK(bl));
                for(int i=l;i<=r;++i)a[i]+=x;
                s[bl].mdy(1,0,s[bl].n-1,l%kuai,r%kuai,x);
                s[bl].shift(0);
            } else {
                if(l==LK(bl))s[bl].shift(x);
                else {
                    s[bl].pd(a+LK(bl));
                    for(int i=l;i<RK(bl);++i)a[i]+=x;
                    s[bl].mdy(1,0,s[bl].n-1,l%kuai,s[bl].n-1,x);
                    s[bl].shift(0); 
                }
                for(int j=bl+1;j<br;++j)s[j].shift(x);
                if(r==RK(br)-1)s[br].shift(x);
                else {
                    s[br].pd(a+LK(br));
                    for(int i=LK(br);i<=r;++i)a[i]+=x;
                    s[br].mdy(1,0,s[br].n-1,0,r%kuai,x);
                    s[br].shift(0);
                }
            }
        } else {
            int bl=l/kuai,br=r/kuai;
            if(bl==br){
                print(max(0ll,s[bl].kagari(a+l,a+r+1,ANS)));
            } else {
                ll ans=max(s[bl].kagari(a+l,a+RK(bl),ANS),s[br].kagari(a+LK(br),a+r+1,ANS));
                ll sum=s[bl].kagari(a+l,a+RK(bl),SUF);
                for(int i=bl+1;i<br;++i)
                    ans=max(ans,s[i]._ppre+sum),
                    ans=max(ans,s[i]._pans),
                    sum+=s[i].sum[1],sum=max(sum,s[i]._psuf),
                    sum=max(sum,0ll);
                ans=max(ans,sum+s[br].kagari(a+LK(br),a+r+1,PRE));
                print(max(0ll,ans));
            }
        }
    }
    fwrite(outbuf,1,O-outbuf,stdout);
} 
;