题意
同样是求字段最大和 不过要求是i在[x1,y1]之间,j在[x2,y2]之间。
思路
首先是两大类情况讨论
一、y1<x2
二、y1>=x2
其次就是一些缩短时间的方法:快读,规避掉数组读入,使用位运算,在每个函数结束后加上return(日常tle太难受了)
代码
#include<iostream>
#include<cmath>
#include<stack>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#define Endl "\n"
typedef long long ll;
const int maxn=1e5+5;
const int mod=1e9+7;
using namespace std;
inline ll read(){
ll x = 0, f = 1; char ch; ch = getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
struct segmentTree{
int lmax,rmax,sum,dat;
}tr[maxn<<2];
int a[maxn];
void up(int p){
int ll=p<<1; int rr=ll|1;
tr[p].sum=tr[ll].sum+tr[rr].sum;
tr[p].lmax=max(tr[ll].lmax,tr[ll].sum+tr[rr].lmax);
tr[p].rmax=max(tr[rr].rmax,tr[rr].sum+tr[ll].rmax);
tr[p].dat=max(max(tr[ll].dat,tr[rr].dat),tr[ll].rmax+tr[rr].lmax);
return ;
}
void build(int p,int l,int r){
if(l==r){
tr[p].dat=tr[p].sum=tr[p].lmax=tr[p].rmax=read();
return ;
}
int mid=(l+r)>>1;
int ll=p<<1;
int rr=ll|1;
build(ll,l,mid);
build(rr,mid+1,r);
up(p);
}
segmentTree query(int p,int l,int r,int ql,int qr){
if(ql<=l&&qr>=r)
return tr[p];
int mid=(l+r)>>1;
int ll=p<<1;
int rr=ll|1;
if(ql>mid)
return query(rr,mid+1,r,ql,qr);
else if(qr<=mid)
return query(ll,l,mid,ql,qr);
else{
segmentTree ans,a,b;
a=query(ll,l,mid,ql,qr);
b=query(rr,mid+1,r,ql,qr);
ans.sum=a.sum+b.sum;
ans.dat=max(a.dat,a.rmax+b.lmax);
ans.dat=max(ans.dat,b.dat);
ans.lmax=max(a.lmax,a.sum+b.lmax);
ans.rmax=max(b.rmax,b.sum+a.rmax);
return ans;
}
}
ll t,m,res=0;
int x1,y11,x2,y2;
int main()
{
t=read();
while(t--)
{
int n;
n=read();
build(1,1,n);
m=read();
while(m--)
{
x1=read(),y11=read(),x2=read(),y2=read();
if(y11<x2)
{
res=query(1,1,n,y11,x2).sum;
if(x1 < y11)res+=max(0,query(1,1,n,x1,y11-1).rmax);
if(x2 < y2) res+=max(0,query(1,1,n,x2+1,y2).lmax);
}
else
{
ll res1 = query(1,1,n,x1,x2).rmax;
if(x2<y2) res1+=max(0,query(1,1,n,x2+1,y2).lmax);
ll res2=query(1,1,n,x2,y11).dat;
ll res3 = query(1,1,n,x2,y11).rmax;
if(y11<y2) res3+=max(0,query(1,1,n,y11+1,y2).lmax);
res=max(max(res1,res2),res3);
// cout<<"here 2 "<<res<<Endl;
}
cout<<res<<Endl;
}
}
return 0;
}