版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/88784347
传送门
解析:
这是什么SB分类讨论题啊。。。
首先不会任意子区间最大子段和的请参见GSS3
那么考虑两个区间有没有相交。
如果没有,显然中间的部分是必选的。然后两边分别选择最大前缀和和最大后缀和就行了。
如果相交了,会稍微复杂一些。
相交部分是可以任意选择的。
然后对于几个前后缀分类讨论一下就行了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
re char c;
re bool f=0;
while(!isdigit(c=gc()))f^=c=='-';re int num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return f?-num:num;
}
}
using namespace IO;
inline int max(int a,int b){return a<b?b:a;}
cs int N=1e4+4;
struct node{
int lmx,rmx,sum,mx;
node(){}
node(cs int &_lmx,cs int &_rmx,cs int &_sum,cs int &_mx):lmx(_lmx),rmx(_rmx),sum(_sum),mx(_mx){}
friend node operator+(cs node &l,cs node &r){
node t;
t.sum=l.sum+r.sum;
t.lmx=max(l.lmx,r.lmx+l.sum);
t.rmx=max(r.rmx,l.rmx+r.sum);
t.mx=max(max(l.mx,r.mx),l.rmx+r.lmx);
return t;
}
}t[N<<2],unit=node(-0x3f3f3f3f,-0x3f3f3f3f,0,-0x3f3f3f3f);
int sum[N];
inline void build(int k,int l,int r){
if(l==r){
sum[l]=sum[l-1]+(t[k].sum=t[k].lmx=t[k].rmx=t[k].mx=getint());
return ;
}
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
t[k]=t[k<<1]+t[k<<1|1];
}
inline node query(int k,int l,int r,cs int &ql,cs int &qr){
if(ql<=l&&r<=qr)return t[k];
int mid=(l+r)>>1;
if(qr<=mid)return query(k<<1,l,mid,ql,qr);
if(mid<ql)return query(k<<1|1,mid+1,r,ql,qr);
return query(k<<1,l,mid,ql,qr)+query(k<<1|1,mid+1,r,ql,qr);
}
int n,m,x_1,x_2,y_1,y_2;
inline node query(int l,int r){
if(r<l)return unit;
return query(1,1,n,l,r);
}
node t1,t2,t3;
inline void solve(){
n=getint();
build(1,1,n);
m=getint();
while(m--){
x_1=getint(),y_1=getint(),x_2=getint(),y_2=getint();
if(y_1<x_2){
std::cout<<sum[x_2-1]-sum[y_1]+query(x_1,y_1).rmx+query(x_2,y_2).lmx<<"\n";
continue;
}
t1=query(x_2,y_1);
t2=query(x_1,x_2-1);
t3=query(y_1+1,y_2);
std::cout<<max(t1.mx,max(t2.rmx+max(t1.lmx,t1.sum+t3.lmx),t1.rmx+t3.lmx))<<"\n";
}
}
int T;
signed main(){
T=getint();
std::ios::sync_with_stdio(false);
std::cout.tie(NULL);
while(T--)solve();
return 0;
}