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. doker基础

    去 Docker Hub 上拉取一个叫 hello-world 的集装箱docker pull hello-world然后让这个集装箱跑起来docker run hello-world查看本机所安装的 ...

  2. maven_默认新建项目jdk1.6_默认配置

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  3. WPF中DataGrid自定义实现最后一行下面跟一个汇总行,类似MT4

    1.先看MT4实现的效果:(图中红框部分),其实就是DataGrid在最后一行下面跟一个汇总的显示条 2.看我WPF实现的效果,汇总行中的数据可以绑定哦!效果图如下: 我扩展了一下DataGrid控件 ...

  4. Selenium 获取动态js的网页

    Selenium基于webkit实现爬虫功能 http://www.cnblogs.com/luxiaojun/p/6144748.html https://www.cnblogs.com/chenq ...

  5. C# WinForm TreeView选择父节点子节点全选

    //设置标志,防止死循环 bool check = false; public void TV_AfterCheck(object sender, TreeViewEventArgs e) { if ...

  6. C、C++笔记

    2017年6月 阅读书籍<C和指针> #if 0 #endif 比注释掉代码好.(<C和指针>2017.06.07) 全局变量和全局静态变量的区别 1)全局变量是不显式用sta ...

  7. 零元学Expression Blend 4 - Chapter 28 ListBox的基本运用与更改预设样式

    原文:零元学Expression Blend 4 - Chapter 28 ListBox的基本运用与更改预设样式 本章将先教大家认识ListBox的基本运用与更改预设样式 本章将先教大家认识List ...

  8. 为什么360、百度、腾讯出的Mac端云盘客户端都只有同步盘?(用户量小,同步盘开发成本低,Linux下都没有客户端)

    如题,顾名思义,同步盘是用来同步的,不具备增量的功能,像这三家在Windows端出的客户端都是即有同步也有增量的. 陆续出来的,可能大家更多的是跟随策略,不得不提dropbox是这样的形式.mac电脑 ...

  9. Android零基础入门第78节:四大组件的纽带——Intent

    前面学习Activity时己经多次使用了 Intent,当一个Activity需要启动另一个Activity时, 程序并没有直接告诉系统要启动哪个Activity,而是通过Intent来表达自己的意图 ...

  10. AngularJS的简单使用(入门级)

    AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中. AngularJS有着诸多特性,最为 ...