https://cn.vjudge.net/contest/244153#problem/I
最经典的,求最大长方形面积
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<stack>
#define maxn 100005
#define inf 0x3f3f3f3f
#define eps 1e-6
using namespace std;
typedef long int ll;
int a[maxn], l[maxn], r[maxn], s[maxn], p;
int main()
{
int n;
while (scanf("%d", &n) && n){
s[0] = 0, p = 0;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i){
while (p > 0 && a[s[p]] >= a[i]) --p;
l[i] = s[p] + 1;
s[++p] = i;
}
s[0] = n + 1, p = 0;
for (int i = n; i >= 1; --i){
while (p > 0 && a[s[p]] >= a[i]) --p;
r[i] = s[p] - 1;
s[++p] = i;
}
long long ans = 0;
for (int i = 1; i <= n; ++i) ans = max(ans, (long long)a[i] * (r[i] - l[i] + 1));
printf("%lld\n", ans);
}
return 0;
}
单调栈经典应用太多了,比如求所有区间的最大值之和。
http://www.51nod.com/Challenge/Problem.html#problemId=1215
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 5e4 + 10;
int a[maxn], l[maxn], r[maxn], s[maxn], p;
int main()
{
int n;
scanf("%d", &n);
s[0] = 0, p = 0;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i <= n; ++i){
while (p > 0 && a[s[p]] < a[i]) --p;
l[i] = s[p] + 1;
s[++p] = i;
}
s[0] = n + 1, p = 0;
for (int i = n; i >= 1; --i){
while (p > 0 && a[s[p]] <= a[i]) --p;
r[i] = s[p] - 1;
s[++p] = i;
}
ll ma = 0, mi = 0;
//for (int i = 1; i <= n; ++i) cout << l[i] << " " << r[i] << endl;
for (int i = 1; i <= n; ++i) ma += (ll)a[i] * (i - l[i] + 1) * (r[i] - i + 1);
s[0] = 0, p = 0;
for (int i = 1; i <= n; ++i){
while (p > 0 && a[s[p]] > a[i]) --p;
l[i] = s[p] + 1;
s[++p] = i;
}
s[0] = n + 1, p = 0;
for (int i = n; i >= 1; --i){
while (p > 0 && a[s[p]] >= a[i]) --p;
r[i] = s[p] - 1;
s[++p] = i;
}
//for (int i = 1; i <= n; ++i) cout << l[i] << " " << r[i] << endl;
for (int i = 1; i <= n; ++i) mi += (ll)a[i] * (i - l[i] + 1) * (r[i] - i + 1);
cout << ma - mi << endl;
return 0;
}