poj 2796 单调栈(秒懂)

poj- 2796

在这里插入图片描述
在这里插入图片描述

单调栈维护高度, 前缀和也要维护高度,这题可以看作求max(a[i] * (sum[r[i]] - sum[l[i]])), 其中l[i]和r[i],分别表示第i个数的左边、右边比他小的第一个数的下标:

我知道你们只看这个

#pragma G++ optimize(2)
#pragma GCC optimize(2)
#define DEBUG
#include<iostream>
#include<algorithm>
#include<stack>
#include<vector>
#include<iostream>
#include<climits>
#include<queue>
#include<cassert>
#include<iomanip>
#include<cmath>
#include<string> 
#include<cstdio>
#include<cstring>
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i = (a); i <(b); ++i)
#define _rof(i, a, b) for(int i = (a); i >(b); --i)
#define maxn 100009
#define maxm 109
#define ll long long
#define met(a,b) memset((a),(b), sizeof(a))
#define db double
#define eps 1e-8
using namespace std;
int n;
int le = 1, ri = 1;
ll h[maxn], r[maxn], sum[maxn], s[maxn], l[maxn];
int main()
{
 //freopen("C:\\Users\\Jason.Z\\Desktop\\out.txt", "w", stdout);
 while (~scanf("%d", &n)) {
  _rep(i, 1, n) {
   scanf("%lld", &h[i]);
   sum[i] = h[i] + sum[i - 1];
  }
  int top = 0;
  _rep(i, 1, n) {
   while (top && h[s[top]] >= h[i]) top--;//栈单增,遇到比我高的就pop
   l[i] = top ? s[top] + 1 : 1;//若栈空(没有数比我小),则l[i] = 1, 反之则取比我小的这个数的前一个 
   s[++top] = i;
  }
  top = 0;
  _rev(i, n, 1) {
   while (top && h[s[top]] >= h[i])top--;
   r[i] = top ? s[top] - 1 : n;//若栈空(右边没有比我小的数)则,取到最右n,反之则取比我小的这个数的前一个
   s[++top] = i;
  }
  ll out = 0;
  le = 1, ri = 1;
  _rep(i, 1, n) {
   ll ans = h[i] * (sum[r[i]] - sum[l[i] - 1]);//区间包括左端点l[i],即sum[r[i]] - sum[l[i] - 1]
   if (ans > out) {
    out = ans;
    le = l[i];
    ri = r[i];
   }
  }
  cout << out << endl;
  cout << le << " " << ri << endl << endl;
 }
}

若有错谬之处欢迎指正

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值