题目:https://nanti.jisuanke.com/t/38228
这题题解参考网上大佬的。
程序的L[i],R[i]代表a[i]这个点的值在区间 [L[i],R[i]] 中最小的并且能拓展到最左为L[i],最右为R[i]。
然后如果a[i]>0的情况就是 : a[i]*(Sum[R[i]]-Sum[L[i]-1])
如果a[i]<0那么这题就会变得复杂许多。需要预处理出Lmin[i],Rmin[i],Lmin[i]代表:以i为右端点的时候 Lmin[i]为左端点能得到区间和最小,Rmin[i]同理。
那么a[i]<0的最大值就是:a[i]*(Sum[ max(L[i],Lmin[i]) ]-Sum[ min(R[i],Rmin[i])-1 ])
具体细节可以看代码:
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=5e5+10; const int INF=0x3f3f3f3f; LL n,top,a[N],L[N],R[N],Sum[N],Lmin[N],Rmin[N]; struct dat{ LL idx,val; }S[N]; int main() { cin>>n; for (int i=1;i<=n;i++) scanf("%lld",&a[i]); for (int i=1;i<=n;i++) Sum[i]=Sum[i-1]+a[i]; a[n+1]=-INF; for (int i=1;i<=n+1;i++) { while (top && a[i]<S[top].val) { int id=S[top].idx; L[id]=S[top-1].idx+1; R[id]=i-1; top--; } top++; S[top].idx=i; S[top].val=a[i]; } LL sum=0,Max=0,id=0; for (int i=1;i<=n;i++) { sum+=a[i]; Lmin[i]=id+1; if (sum>Max) Max=sum,id=i; } sum=0; Max=0; id=n+1; for (int i=n;i;i--) { sum+=a[i]; Rmin[i]=id-1; if (sum>Max) Max=sum,id=i; } LL ans=-INF; for (int i=1;i<=n;i++) if (a[i]>=0) ans=max(ans,a[i]*(Sum[R[i]]-Sum[L[i]-1])); else { LL lm=max(L[i],Lmin[i]),rm=min(R[i],Rmin[i]); ans=max(ans,a[i]*(Sum[rm]-Sum[lm-1])); } cout<<ans<<endl; return 0; }