1.​​题目链接​​。题目大意:给一个直方图,求出最大连续的矩形面积。emm。

2.分析:其实很容易想到,我们可以从最高的的那个矩形开始枚举,看看它的左右分别能够到达哪里,把面积算出来,取最大。但是这样会T,因为这显然是N方的。但是这个思路没有错误,我们要做一点优化,就是加一些预处理的信息,我们把每个矩形能够达到的左右边界预处理出来,然后再枚举。这样就AC了。这里的主要问题就是如何预处理每一个矩形的左右边界,对于第i个矩形,我们用数组l[i],r[i]保存这个矩形的左右边界,那么对于每一个i,假设我们现在正在预处理左边界,我们只需要把他和他的左边的相比,一直找到一个比它小的,然后记录。emmm,不是很难吧应该。代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
#define ll long long
ll a[N], dp[N], l[N], r[N];
ll n;
#pragma warning(disable:4996)
int main()
{
while (~scanf("%lld", &n)&&n)
{
for (int i = 1; i <=n; i++)
{
scanf("%lld", &a[i]);
}
ll mmax = -1;
l[1] = 1;
r[n] = n;
for (int i = 2; i <= n; i++)
{
int t = i;
/*
注意这里的一个小小的优化,不用一直循环的找,那样还是会T。
我们要利用好已经处理出来的结果*/
while (t > 1 && a[i] <= a[t - 1])
t = l[t - 1];
l[i] = t;
}
for (int i = n - 1; i>= 1; i--)
{
int t = i;
while (t <n && a[i] <= a[t + 1])
t = r[t + 1];
r[i] = t;
}
for (int i = 1; i <= n; i++)
{
mmax = max(mmax, (r[i] - l[i]+1)*a[i]);
}
printf("%lld\n", mmax);
}
}