传送门
以前讲过的题,会最大子段和然后分类讨论一下就好了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define N 10005
#define ls cur<<1
#define rs cur<<1|1
#define int long long
using namespace std;
inline int rd(){
int x=0,f=1;char c=' ';
while(c<'0' || c>'9') f=c=='-'?-1:1,c=getchar();
while(c<='9' && c>='0') x=x*10+c-'0',c=getchar();
return x*f;
}
int t,n,m,a[N];
struct Node{
int l,r,sum,mx,lmx,rmx;
Node(){l=r=sum=mx=lmx=rmx=0;}
}node[N<<2];
inline void pushup(int cur){
node[cur].sum=node[ls].sum+node[rs].sum;
node[cur].lmx=max(node[ls].lmx,node[ls].sum+node[rs].lmx);
node[cur].rmx=max(node[rs].rmx,node[rs].sum+node[ls].rmx);
node[cur].mx=max(max(node[ls].mx,node[rs].mx),node[ls].rmx+node[rs].lmx);
}
void build(int cur,int L,int R){
if(L==R){
node[cur].l=node[cur].r=L;
node[cur].sum=node[cur].mx=node[cur].lmx=node[cur].rmx=a[L];
return;
}
int mid=(L+R)>>1;
build(ls,L,mid); build(rs,mid+1,R);
node[cur].l=node[ls].l,node[cur].r=node[rs].r;
pushup(cur); return;
}
Node query(int cur,int L,int R){
if(L<=node[cur].l && node[cur].r<=R) return node[cur];
int mid=(node[cur].l+node[cur].r)>>1;
if(R<=mid) return query(ls,L,R);
if(L>mid) return query(rs,L,R);
Node x,y,res;
x=query(ls,L,R); y=query(rs,L,R);
res.sum=x.sum+y.sum;
res.lmx=max(x.lmx,x.sum+y.lmx);
res.rmx=max(y.rmx,y.sum+x.rmx);
res.mx=max(max(x.mx,y.mx),x.rmx+y.lmx);
return res;
}
signed main(){
t=rd();
int x1,x2,y1,y2;
while(t--){
n=rd();
for(int i=1;i<=n;i++) a[i]=rd();
build(1,1,n);
m=rd();
while(m--){
x1=rd(),y1=rd(),x2=rd(),y2=rd();
if(y1+1<x2)
printf("%lld\n",query(1,x1,y1).rmx+query(1,y1+1,x2-1).sum+query(1,x2,y2).lmx);
else if(x1==x2 && y1==y2) printf("%lld\n",query(1,x2,y2).mx);
else if(x1<=x2 && y1>=y2){
Node x=x1<x2?query(1,x1,x2-1):x,y=query(1,x2,y2);
printf("%lld\n",max(x.rmx+y.lmx,y.mx));
}
else if(x1>=x2 && y1<=y2){
Node x=query(1,x1,y1),y=y1<y2?query(1,y1+1,y2):y;
printf("%lld\n",max(x.rmx+y.lmx,x.mx));
}
else{
Node x,y,z; int ans=0;
if(x1<x2) x=query(1,x1,x2-1);
else x.rmx=0;
y=query(1,x2,y2); ans=x.rmx+y.lmx;
x=query(1,x1,y1);
if(x2<=y1) y=query(1,x2,y1),ans=max(ans,y.mx);
if(y1<y2) z=query(1,y1+1,y2);
else z.lmx=0;
ans=max(ans,x.rmx+z.lmx);
printf("%lld\n",ans);
}
}
}
return 0;
}