题目链接:https://nanti.jisuanke.com/t/38228
解题思路:典型的单调栈问题,除了一个复数情况可能需要多考虑一下
单调栈讲解:https://www.cnblogs.com/violet-acmer/p/9780638.html
AC代码
#include
#include
using namespace std;
const int maxn = 5e5+50;
long long sum[maxn];
int num[maxn];
int l[maxn];
int r[maxn];
long long minl[maxn];//往左找最小和
stacksta;
void init()
{
while(!sta.empty())
sta.pop();
}
int main()
{
ios::sync_with_stdio(false);
init();
int n;
cin >> n;
sum[0] = 0;
for(int i = 1; i <= n; ++i)
{
cin >> num[i];
sum[i] = sum[i-1]+num[i];
}
for(int i = 1; i <= n; ++i)
{
while(!sta.empty() && num[sta.top()]>=num[i])
sta.pop();
l[i] = (sta.empty()?1:(sta.top()+1));
sta.push(i);
}
init();
for(int i = n; i >= 1; --i)
{
while(!sta.empty() && num[sta.top()]>=num[i])
sta.pop();
r[i] = (sta.empty()?n:(sta.top()-1));
sta.push(i);
}
for(int i = 1; i <= n; ++i)
{
if(num[i] < 0)
{
for(int j = i; j >= l[i]; --j)
minl[i] = min(minl[i], sum[i]-sum[j-1]);
}
}
long long ans = 0;
for(int i = 1; i <= n; ++i)
{
if(num[i] >= 0)
{
long long temp = sum[r[i]] - sum[l[i]-1];
ans = max(ans, temp*num[i]);
}
else
{
long long minn = 0;
for(int j = i+1; j <= r[i]; ++j)
minn = min(minn, sum[j]-sum[i]);//往又找最小和
ans = max(ans, num[i]*(minl[i]+minn));
}
}
cout << ans << '\n';
return 0;
}