题目
分析
如果枚举区间,先不谈求最小值还得用线段树优化到
,光是枚举就要
于是尝试枚举最小值
,再往两边拓展到第一次出现威胁到最小值的值之前
,再尝试对这个过程进行优化,采用单调栈
从左往右,对每个值求左边第一个更小的值位置p,l = p+1;若不存在,则 l = 1
类似,r = p-1;r = n
代码
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 3e5+10;
int n, a[N], l[N], r[N];
stack<int> s;
ll ans;
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", a+i);
for(int i = 1; i <= n; i++)
{
while(s.size() && a[s.top()] >= a[i])
s.pop();
if(s.size()) l[i] = s.top() + 1;
else l[i] = 1;
s.push(i);
}
while(s.size()) s.pop();
for(int i = n; i; i--)
{
while(s.size() && a[s.top()] >= a[i])
s.pop();
if(s.size()) r[i] = s.top() - 1;
else r[i] = n;
s.push(i);
}
for(int i = 1; i <= n; i++)
ans = max(ans, 1ll * (r[i] - l[i] + 1) * a[i]);
printf("%lld", ans);
}