You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| <= 10000 , 1 <= N <= 10000 ). A query is defined as follows: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 <= j <= y2 and x1 <= x2 , y1 <= y2 }. Given M queries (1 <= M <= 10000), your program must output the results of these queries.
Input
The first line of the input consist of the number of tests cases <= 5. Each case consist of the integer N and the sequence A. Then the integer M. M lines follow, contains 4 numbers x1, y1, x2 y2.
Output
Your program should output the results of the M queries for each test case, one query per line.
参见http://blog.csdn.net/sdfzyhx/article/details/51388593。
当y1<x2时,即起点可选区间与终点可选区间不重叠,则答案为lmax(x1,y1)+sum(y1,x2)+rmax(x2,y2)。
否则,则需对y1和x2所在位置进行讨论。
ans=max(max(x2,y1),rmax(x1,y2)+lmax(y1,y2),rmax(x1,x2)+lmax(x2,y2))。
第一种为两端点都在重叠部分,第二种为起点在独属区域,第三种为终点在独属区域。
【注:此处为了直观,略去边界的+1,-1。详见代码。】
#include<cstdio>
#include<cstring>
#define M(a) memset(a,0,sizeof(a))
struct node
{
int lch,rch,l,r,lmax,rmax,max,sum;
}t[200010];
struct ans
{
int l,r,max,s;
};
int n,nn,a[50010];
int mx(int x,int y)
{
return x>y?x:y;
}
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
if (l==r)
{
t[p].lmax=t[p].rmax=t[p].max=t[p].sum=a[l];
return;
}
int mid=(t[p].l+t[p].r)/2;
t[p].lch=++nn;
build(nn,l,mid);
t[p].rch=++nn;
build(nn,mid+1,r);
t[p].sum=t[t[p].lch].sum+t[t[p].rch].sum;
t[p].lmax=mx(t[t[p].lch].lmax,t[t[p].lch].sum+t[t[p].rch].lmax);
t[p].rmax=mx(t[t[p].rch].rmax,t[t[p].rch].sum+t[t[p].lch].rmax);
t[p].max=mx(mx(t[t[p].lch].max,t[t[p].rch].max),t[t[p].lch].rmax+t[t[p].rch].lmax);
}
ans find(int p,int l,int r)
{
ans al,ar,a;
if (l>r)
{
a.l=a.r=a.s=a.max=0;
return a;
}
if (t[p].l==l&&t[p].r==r)
{
a.l=t[p].lmax;
a.r=t[p].rmax;
a.max=t[p].max;
a.s=t[p].sum;
return a;
}
int mid=(t[p].l+t[p].r)/2;
if (r<=mid) return find(t[p].lch,l,r);
if (l>=mid+1) return find(t[p].rch,l,r);
al=find(t[p].lch,l,mid);
ar=find(t[p].rch,mid+1,r);
a.l=mx(al.l,al.s+ar.l);
a.r=mx(ar.r,ar.s+al.r);
a.s=al.s+ar.s;
a.max=mx(mx(al.max,ar.max),al.r+ar.l);
return a;
}
int main()
{
int i,j,k,m,p,q,x,y,z,T,x1,x2,y1,y2;
scanf("%d",&T);
while (T--)
{
M(a);
M(t);
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
nn=1;
build(1,1,n);
scanf("%d",&m);
for (i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
if (x2<=y1)
{
x=find(1,x2,y1).max;
y=find(1,x1,y1).r+find(1,y1+1,y2).l;
z=find(1,x1,x2-1).r+find(1,x2,y2).l;
printf("%d\n",mx(mx(x,y),z));
}
else
printf("%d\n",find(1,x1,y1).r+find(1,y1+1,x2-1).s+find(1,x2,y2).l);
}
}
}