题目链接:点击打开链接
题意:
T个测试数据
n个数字
q个询问
每个询问 : [x1, y1] [x2, y2]
问:
int ans = -inf;
for(int i = x1; i <= y1; i++)
for(int j = max(x2, i); j <= y2; j++)
ans = max(ans, query(i, j));
思路:
query_L(int l, int r) 求的是在区间[l,r]内 ,左端点为l的最大子段和。
其他和GSS3差不多。
分类讨论一下给定的区间[x1, y1] [x2, y2]
1、若两个区间分离( y1 < x2 ) 则 (y1 , x2) 部分必选,其他部分就尽量拓展
2、若 y1 == x2,则中间这个点必选,其他两边要么不选要么尽量拓展。
3、区间重合时,则类似讨论即可,把区间分成: [x1, y1), [y1,x2] , (x2, y2] ,那么【i,j】落在这3个区间的情况有4种。
在两边区间的情况就和1一样,都在中间区间的情况就是GSS3的问题。
另外2种情况就和2类似。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <math.h>
#include <vector>
#include <map>
using namespace std;
#define N 10005
#define Lson(x) tree[x].l
#define Rson(x) tree[x].r
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Sum(x) tree[x].sum
#define Max(x) tree[x].max
#define Lmax(x) tree[x].lmax
#define Rmax(x) tree[x].rmax
struct node{
int l, r;
int mid(){return (l+r)>>1;}
int lmax, rmax, max, sum;
}tree[N<<2];
int n, a[N], Q;
int query_sum(int l, int r, int id){
if(l == Lson(id) && Rson(id) == r)return Sum(id);
int mid = tree[id].mid();
if(mid < l)
return query_sum(l, r, R(id));
else if(r<=mid)
return query_sum(l, r, L(id));
else return query_sum(l, mid, L(id)) + query_sum(mid+1, r, R(id));
}
void push_up(int id){
Lmax(id) = max(Lmax(L(id)), Sum(L(id)) + Lmax(R(id)));
Rmax(id) = max(Rmax(R(id)), Sum(R(id)) + Rmax(L(id)));
Sum(id) = Sum(L(id)) + Sum(R(id));
Max(id) = max(max(Max(L(id)), Max(R(id))), Rmax(L(id)) + Lmax(R(id)));
}
void updata_point(int val, int id){Lmax(id) = Rmax(id) = Max(id) = Sum(id) = val;}
void build(int l, int r, int id){
Lson(id) = l; Rson(id) = r;
if(l == r)
{
updata_point(a[l], id);
return;
}
int mid = tree[id].mid();
build(l, mid, L(id));
build(mid+1, r, R(id));
push_up(id);
}
int query_l(int l, int r, int id){
if(l == Lson(id) && Rson(id) == r) return Lmax(id);
int mid = tree[id].mid();
if(mid < l)
return query_l(l, r, R(id));
else if(r <= mid)
return query_l(l, r, L(id));
int lans = query_l(l, mid, L(id)), rans = query_l(mid+1, r, R(id));
return max(lans, Sum(L(id)) + rans);
}
int query_r(int l, int r, int id){
if(l == Lson(id) && Rson(id) == r) return Rmax(id);
int mid = tree[id].mid();
if(mid < l)
return query_r(l, r, R(id));
else if(r <= mid)
return query_r(l, r, L(id));
int lans = query_r(l, mid, L(id)), rans = query_r(mid+1, r, R(id));
return max(rans, Sum(R(id)) + lans);
}
int query_L(int l, int r, int id){
if(l == Lson(id) && Rson(id) == r) return Lmax(id);
int mid = tree[id].mid();
if(mid < l)
return query_L(l, r, R(id));
else if(r <= mid)
return query_L(l, r, L(id));
int lans = query_L(l, mid, L(id)), rans = query_L(mid+1, r, R(id));
return max(lans, query_sum(l, mid, id) + rans);
}
int query_R(int l, int r, int id){
if(l == Lson(id) && Rson(id) == r) return Rmax(id);
int mid = tree[id].mid();
if(mid < l)
return query_R(l, r, R(id));
else if(r <= mid)
return query_R(l, r, L(id));
int lans = query_R(l, mid, L(id)), rans = query_R(mid+1, r, R(id));
return max(rans, query_sum(mid+1, r, id) + lans);
}
int query(int l, int r, int id){
if(l == Lson(id) && Rson(id) == r)return Max(id);
int mid = tree[id].mid();
if(mid < l)
return query(l, r, R(id));
else if(r<=mid)
return query(l, r, L(id));
int lans = query(l, mid, L(id)), rans = query(mid+1, r, R(id));
int ans = max(lans, rans);
return max(ans, query_r(l, mid, L(id)) + query_l(mid+1, r, R(id)));
}
void solve(){
scanf("%d",&n);
for(int i = 1; i <= n; i++)scanf("%d",&a[i]);
build(1, n, 1);
scanf("%d",&Q);
while(Q--){
int x1, x2, y1, y2, ans;
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
if(y1<x2)
{
ans = query_R(x1, y1, 1) + query_L(x2, y2, 1);
if(y1+1 <= x2-1)
ans += query_sum(y1+1, x2-1, 1);
}
else if(y1 == x2){
ans = query_sum(y1, x2, 1);
if(x1 <= y1-1) ans += max(0, query_R(x1, y1-1, 1));
if(x2+1 <= y2) ans += max(0, query_L(x2+1, y2, 1));
}
else
{
ans = query(x2, y1, 1);// i,j都在中间
int tmp = query_R(x1, x2, 1) + query_L(y1, y2, 1);// i,j都在2边
if(x2+1 <= y1-1)
tmp += query_sum(x2+1, y1-1, 1);
ans = max(ans, tmp);
tmp = query_L(x2, y2, 1);
if(x1 <= x2-1)
tmp += query_R(x1, x2-1, 1);
ans = max(ans, tmp);
tmp = query_R(x1, y1, 1);
if(y1+1 <= y2)
tmp += query_L(y1+1, y2, 1);
ans = max(ans, tmp);
}
printf("%d\n",ans);
}
}
int main(){
int T;scanf("%d",&T);
while(T--)
solve();
return 0;
}