描述
题解
类似于在(某一区间中最小值*此区间所有元素之和)最大
的问题,这里是(某一区间中最小值*此区间宽度)最大
的问题。
此类问题可以使用单调栈来实现,使问题可以在O(N)的复杂度中解决。
不管是单调递增还是递减均可,这里使用的是单调递减栈。
代码
#include <iostream>
#include <cstdio>
#include <stack>
typedef long long ll;
using namespace std;
const int MAXN = 5e4 + 10;
struct a
{
ll value;
int left;
int right;
} A[MAXN];
int main(int argc, const char * argv[])
{
int N;
cin >> N;
// 单调递减栈
stack<a> AA;
int key = 0;
a num;
for (int i = 1; i <= N; i++)
{
scanf("%lld", &num.value);
num.left = num.right = i;
if (AA.empty())
{
AA.push(num);
}
else
{
a pop = {0, 0, 0};
while (!AA.empty() && AA.top().value > num.value)
{
AA.top().right = i - 1;
A[key++] = pop = AA.top();
AA.pop();
}
if (pop.value)
{
num.left = !AA.empty() && AA.top().value == num.value ? AA.top().left : pop.left;
}
else
{
num.left = !AA.empty() && AA.top().value == num.value ? AA.top().left : i;
}
AA.push(num);
}
}
// 全部出栈
while (!AA.empty())
{
AA.top().right = N;
A[key++] = AA.top();
AA.pop();
}
ll ans = 0;
for (int i = 1; i <= N; i++)
{
ans = max((A[i].right - A[i].left + 1) * A[i].value, ans);
}
cout << ans << '\n';
return 0;
}