http://poj.org/problem?id=2796

题意:给出n个数,问一个区间里面最小的元素*这个区间元素的和的最大值是多少。

思路:只想到了O(n^2)的做法。

参考了http://www.cnblogs.com/ziyi--caolu/archive/2013/06/23/3151556.html的写法,用单调栈可以优化到O(n)。

对于每个元素,维护这个元素向前延伸比它大的有多少个,向后延伸比它小的有多少个。即该元素是处于山谷。

那么如何用单调栈维护这个呢?

首先这个栈是单调递增的,对于当前栈顶的元素top,如果比要进栈的元素now大,那么是top要出栈,那么top出栈后的栈顶元素suftop一定比top小,那么代表着suftop可以向后延伸到top的向后延伸位置,因为入栈元素now一定比top小,那么now可以向前延伸到top向前延伸的位置。

预处理一个前缀和,当元素出栈的时候就可以直接计算了。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
#define N 100010
typedef long long LL;
struct node {
int pre, suf, id;
LL num;
} p[N];
LL sum[N]; void solve(int n) {
for(int i = ; i <= n; i++) {
scanf("%lld", &p[i].num);
p[i].pre = p[i].suf = ; p[i].id = i;
sum[i] = sum[i-] + p[i].num;
}
LL ans = -; int l, r; // 有0这个坑点
stack<node> sta;
sta.push(p[]);
for(int i = ; i <= n; i++) {
while(!sta.empty() && sta.top().num > p[i].num) {
node top = sta.top(); sta.pop();
if(!sta.empty()) sta.top().suf += top.suf;
p[i].pre += top.pre;
LL res = sum[top.id + top.suf - ] - sum[top.id - top.pre];
res *= top.num;
if(res > ans) {
ans = res;
l = top.id - top.pre + ;
r = top.id + top.suf - ;
}
}
sta.push(p[i]);
}
while(!sta.empty()) {
node top = sta.top(); sta.pop();
if(!sta.empty()) sta.top().suf += top.suf;
LL res = sum[top.id + top.suf - ] - sum[top.id - top.pre];
res *= top.num;
if(res > ans) {
ans = res;
l = top.id - top.pre + ;
r = top.id + top.suf - ;
}
}
printf("%lld\n%d %d\n", ans, l, r);
} int main() {
int n;
while(~scanf("%d", &n)) solve(n);
return ;
}

POJ 2796:Feel Good(单调栈)的更多相关文章

  1. poj 2796 Feel Good单调栈

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20408   Accepted: 5632 Case T ...

  2. poj 2796 Feel Good 单调栈区间问题

    Feel Good 题意:给你一个非负整数数组,定义某个区间的参考值为:区间所有元素的和*区间最小元素.求该数组中的最大参考值以及对应的区间. 比如说有6个数3 1 6 4 5 2 最大参考值为6,4 ...

  3. POJ 3658 Artificial Lake (单调栈)

    题意: 析:利用单调栈,维护一个单调递增的栈,首先在最低的平台开始,每次向两边进行扩展,寻找两边最低的,然后不断更新宽度. 代码如下: #pragma comment(linker, "/S ...

  4. poj 2559 Largest Rectangle(单调栈)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 26549 ...

  5. POJ - 2796 Feel Good 单调递增栈+前缀和

    Feel Good Bill is developing a new mathematical theory for human emotions. His recent investigations ...

  6. POJ 3415 后缀数组+单调栈

    题目大意: 给定A,B两种字符串,问他们当中的长度大于k的公共子串的个数有多少个 这道题目本身理解不难,将两个字符串合并后求出它的后缀数组 然后利用后缀数组求解答案 这里一开始看题解说要用栈的思想,觉 ...

  7. poj 2796 Feel Good 单调队列

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8753   Accepted: 2367 Case Ti ...

  8. [poj 2796]单调栈

    题目链接:http://poj.org/problem?id=2796 单调栈可以O(n)得到以每个位置为最小值,向左右最多扩展到哪里. #include<cstdio> #include ...

  9. POJ 2796 Feel Good 【单调栈】

    传送门:http://poj.org/problem?id=2796 题意:给你一串数字,需要你求出(某个子区间乘以这段区间中的最小值)所得到的最大值 例子: 6 3 1 6 4 5 2 当L=3,R ...

随机推荐

  1. LeapMotion Demo2

    原文:LeapMotion Demo2    官方doc有四个手势,最近尝试实现对握拳的识别,并能在我的程序界面上体现出来.    调试过程较为繁琐,幸好最终效果还差强人意! 首先看看我的效果图:   ...

  2. XF 标签和文本控件

    <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http:/ ...

  3. PHP获得指定日期所在星期的第一天和最后一天

    function getdays($day){ $lastday=date('Y-m-d',strtotime("$day Sunday")); $firstday=date('Y ...

  4. python selenium chrome 测试

    #coding=utf-8 from selenium import webdriver from selenium.webdriver.common.keys import Keys from se ...

  5. 零元学Expression Blend 4 - Chapter 25 以Text相关功能就能简单做出具有设计感的登入画面

    原文:零元学Expression Blend 4 - Chapter 25 以Text相关功能就能简单做出具有设计感的登入画面 本章将交大家如何运用Blend 4 内的Text相关功能做出有设计感的登 ...

  6. 零元学Expression Blend 4 - Chapter 11 用实例了解布局容器系列-「Border」

    原文:零元学Expression Blend 4 - Chapter 11 用实例了解布局容器系列-「Border」 将教大家以实做案例认识Blend 4 的布局容器,此章介绍的布局容器是Blend ...

  7. Android零基础入门第49节:AdapterViewFlipper图片轮播

    原文:Android零基础入门第49节:AdapterViewFlipper图片轮播 上一期学习了ExpandableListView的使用,你已经掌握了吗?本期开始学习AdapterViewFilp ...

  8. Twitter的分布式自增ID算法snowflake(雪花算法) - C#版

    概述 分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的.有些时候我们希望能使用一种简 ...

  9. 这里有123个黑客必备的Python工具!

    123个Python渗透测试工具,当然不仅于渗透~ 如果你想参与漏洞研究.逆向工程和渗透,我建议你时候用Python语言.Python已经有很多完善可用的库,我将在这里把他们列出来. 这个清单里的工具 ...

  10. pip升级到18.0版本过程中报错解决方法

    我这台电脑是windows10系统,一般在cmd命令行界面下执行pip的升级命令:pip install –upgrade pip 安装的时候,会有拒绝访问报错:这个时候应该是权限的问题,于是在win ...