区间最大子段和 cid=1761#problem/E
题意: 求子段的左右端点被分别限制在对应区间中的最大子段和
两个限制区间的相对位置分五种情况讨论,用线段树查询区间子段和
#include<bits/stdc++.h>
#define ls (node<<1)
#define rs (node<<1|1)
using namespace std;
typedef long long ll;
const int N=100005;
int n,m;
ll a[N];
ll f[N][20];
ll g[N][20];
ll sum[N];
struct Segtree
{
ll max,vl,vr,sum;
}Tree[N<<3];
void updata(int node)
{
Tree[node].max=max(Tree[ls].max,max(Tree[rs].max,Tree[ls].vr+Tree[rs].vl));
Tree[node].sum=Tree[ls].sum+Tree[rs].sum;
Tree[node].vl=max(Tree[ls].vl,Tree[ls].sum+Tree[rs].vl);
Tree[node].vr=max(Tree[rs].vr,Tree[rs].sum+Tree[ls].vr);
}
void build(int l,int r,int node)
{
if(l==r)
{
Tree[node].sum=a[l];
Tree[node].max=a[l];
Tree[node].vl=a[l];
Tree[node].vr=a[l];
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls);
build(mid+1,r,rs);
updata(node);
}
Segtree query(int l,int r,int node,int sa,int se)
{
if(sa<=l && r<=se)return Tree[node];
int mid=(l+r)>>1;
if(sa>mid)return query(mid+1,r,rs,sa,se);
if(se<=mid)return query(l,mid,ls,sa,se);
Segtree t,lson,rson;
lson=query(l,mid,ls,sa,se);
rson=query(mid+1,r,rs,sa,se);
t.vl=max(lson.vl,lson.sum+rson.vl);t.vr=max(rson.vr,lson.vr+rson.sum);
t.sum=lson.sum+rson.sum;
t.max=max(lson.vr+rson.vl,max(lson.max,rson.max));
return t;
}
void ST_prework()
{
for (int i = 1; i <= n; i++)
{
f[i][0] = sum[i];
g[i][0] = sum[i];
}
for (int i = 1, imax = log2(n); i <= imax; i++)
{
for (int j = 1; j + (1 << i) - 1 <= n; j++)
{
f[j][i] = max(f[j][i - 1], f[j + (1 << i - 1)][i - 1]);
g[j][i] = min(g[j][i - 1], g[j + (1 << i - 1)][i - 1]);
}
}
}
int ST_max(int l, int r)
{
int k = log2(r - l + 1);
return max(f[l][k], f[r - (1 << k) + 1][k]);
}
int ST_min(int l, int r)
{
int k = log2(r - l + 1);
return min(g[l][k], g[r - (1 << k) + 1][k]);
}
int main()
{
int _;
for(scanf("%d",&_);_;_--)
{
scanf("%d",&n);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
ST_prework();
build(1,n,1);
int l1,l2,r1,r2,m;
scanf("%d",&m);
Segtree tmp;
while(m--)
{
scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
ll ans=0;
if(r1<=l2)
{
l1--;
r1--;
if(r1==0)
ans=ST_max(l2,r2);
else if(l1==0)
{
ans=ST_max(l2,r2)-min(0,ST_min(l1+1,r1));
}
else
{
ans=ST_max(l2,r2)-ST_min(l1,r1);
}
}
else if(l2<=l1&&r2>=r1)
{
tmp=query(1,n,1,l1,r1);
ans=max(tmp.max,tmp.vr+query(1,n,1,r1,r2).vl-a[r1]);
}
else if(l1<=l2&&r1>=r2)
{
tmp=query(1,n,1,l2,r2);
ans=max(tmp.max,query(1,n,1,l1,l2).vr+tmp.vl-a[l2]);
}
else if(l2<=l1&&l1<=r2&&r2<=r1)
{
ans=query(1,n,1,l1,r2).max;
}
else if(l1<=l2&&l2<=r1&&r1<=r2)
{
ans=max(query(1,n,1,l1,l2).vr+query(1,n,1,l2,r2).vl-a[l2],max(query(1,n,1,l1,r1).vr+query(1,n,1,r1,r2).vl-a[r1],query(1,n,1,l2,r1).max));
}
printf("%lld\n",ans);
}
}
return 0;
}

浙公网安备 33010602011771号