Feel Good
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 11626   Accepted: 3212
Case Time Limit: 1000MS   Special Judge

Description

Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated to studying how good or bad days influent people's memories about some period of life. 



A new idea Bill has recently developed assigns a non-negative integer value to each day of human life. 



Bill calls this value the emotional value of the day. The greater the emotional value is, the better the daywas. Bill suggests that the value of some period of human life is proportional to the sum of the emotional values of the days in the given period, multiplied
by the smallest emotional value of the day in it. This schema reflects that good on average period can be greatly spoiled by one very bad day. 



Now Bill is planning to investigate his own life and find the period of his life that had the greatest value. Help him to do so.

Input

The first line of the input contains n - the number of days of Bill's life he is planning to investigate(1 <= n <= 100 000). The rest of the file contains n integer numbers a1, a2, ... an ranging from 0 to 106 - the emotional values of the days.
Numbers are separated by spaces and/or line breaks.

Output

Print the greatest value of some period of Bill's life in the first line. And on the second line print two numbers l and r such that the period from l-th to r-th day of Bill's life(inclusive) has the greatest possible value. If there are multiple periods with
the greatest possible value,then print any one of them.

Sample Input

6
3 1 6 4 5 2

Sample Output

60
3 5

题意是给出一个序列,要求的是一个区间,这个区间的最小值乘以这个区间数字的和 是最大值。求这个最大值与这个区间。

看了一晚上,终于算是弄懂了这个代码。实际上这个题目就是要对每一个节点进行扩展,这样扩展的话,复杂度是O(n^2)。减少时间复杂度要用单调栈,单调栈处理的问题就是对每一个节点进行扩展的问题,这个题目要维护的是一个单调递减栈,即从栈顶元素到栈底元素,值是单调递减的,即栈顶元素的值始终是栈的最大值。然后每一个值有属于自己的区间,这个区间目的是为了记录之后的元素向前延伸的用处。

向后延伸就靠从1到n扫描元素,(维护单调递减栈)这样当扫描的元素大于栈顶元素时,直接入栈。

当扫描的元素等于栈顶元素时,不记录,只将区间延伸到后面。

当扫描的元素小于栈顶元素时,这时要计算栈内当前的值。因为扫描的元素时小于栈顶元素的,要求的是一个区间的最小值,所以栈内那些大于该元素的值你会发现没有用处了,只需要将它们的那些区间留下来就对了,这就是向前扩展。

拿题目的sample举例子:

3 1 6 4 5 2

一开始每一个数都有自己的区间:

3(1,1)  1(2,2)  6(3,3)  4(4,4)  5(5,5)  2(6,6)  -1(7,7)后面加一个最小值,为了最后计算栈内元素使用。

先是3入栈。栈内元素 3(1,1)

1<3,首先计算一下栈内元素的值,记录下来。然后要把栈内大于1的全部弹出来,但是把它们的区间留下,栈内就变成了1(1,2)。实际上此时就会知道(1,2)这段区间之内的最小值是1。

6>1,直接入栈,栈内元素变为1(1,2),6(3,3)。

4<6,将6弹出,弹出之前计算值。然后栈内就变为1(1,2),4(3,4)。

5>4,直接入栈。栈内元素是1(1,2),4(3,4),5(5,5)。会发现因为5没有办法向前扩展了所以会知道5只能够在(5,5)的区间内最小,所以说站内元素是在自己区间的左端点与栈顶元素的右端点,这段区间之内满足着最小值的关系。1是在(1,5)这段区间内最小,4是在(3,5)这段区间内最小。这些值都会在碰到扫描的元素小于该元素时计算,记录下来,就是这样单调栈完成了对每一个元素进行左右扩展的目的。

2<5,2<4。要把5(5,5) 4(3,4)分别弹出,它们走之前要计算各自区间的值。

最后是-1,目的就是要将栈内所有元素弹出,计算每一个元素左右扩展的值。

单调栈的知识还有很多,自己还是有很多要去努力理解的。先写这么多,后面在继续添加理解。

代码:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
#pragma warning(disable:4996)
using namespace std; #define N 100001 int a[N], lef[N], stack[N], top;
long long sum[N]; int main()
{
//freopen("i.txt","r",stdin);
//freopen("o.txt","w",stdout); long long ans = -1, tmp;
int i, j, n;
int ll, rr; scanf("%d", &n);
memset(sum, 0, sizeof(sum));
for (i = 1; i <= n; i++)
{
scanf("%d", a + i);
sum[i] = sum[i - 1] + a[i];
}
a[++n] = -1;
top = 0;
for (i = 1; i <= n; i++)
{
if (top == 0 || a[i] > a[stack[top - 1]])
{
stack[top++] = i;
lef[i] = i;
continue;
}
if (a[i] == a[stack[top - 1]])
continue;
while (top >= 1 && a[i] < a[stack[top - 1]])
{
--top;
tmp = 1LL*a[stack[top]] * (sum[i - 1] - sum[lef[stack[top]] - 1]); if (tmp > ans)
{
ll = lef[stack[top]];
rr = i - 1;
ans = tmp;
}
}
lef[i] = lef[stack[top]];
stack[top++] = i;
} printf("%lld\n%d %d\n", ans, ll, rr);
//system("pause");
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ 2796:Feel Good 单调栈经典题的更多相关文章

  1. poj2559/hdu1506 单调栈经典题

    我实在是太菜了啊啊啊啊啊 到现在连个单调栈都不会啊啊啊 写个经典题 #include<cstdio> #include<algorithm> #include<cstri ...

  2. poj 2796 Feel Good单调栈

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

  3. [Usaco2006 Mar]Mooo 奶牛的歌声(单调栈裸题)

    1657: [Usaco2006 Mar]Mooo 奶牛的歌声 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 961  Solved: 679[Submi ...

  4. poj 2559 Largest Rectangle(单调栈)

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

  5. Bad Hair Day POJ - 3250 (单调栈入门题)

    Some of Farmer John's N cows (1 ≤ N ≤ 80,000) are having a bad hair day! Since each cow is self-cons ...

  6. BZOJ1113 海报PLA1(单调栈入门题)

    一,自己思考下 1,先自己思考下 N个矩形,排成一排,现在希望用尽量少的海报去cover住它们. 2,不懂. 着实不懂. 3,分析下,最优性问题对吧,然后就每什么想法了.. 虽然肯定和单调栈和单调队列 ...

  7. 51nod 1437:迈克步 单调栈基础题

    1437 迈克步 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  取消关注 有n只熊.他们站成一排队伍,从左到右依次1到 ...

  8. poj3250(单调栈模板题)

    题目链接:https://vjudge.net/problem/POJ-3250 题意:求序列中每个点右边第一个>=自身的点的下标. 思路:简单介绍单调栈,主要用来求向左/右第一个小于/大于自身 ...

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

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

随机推荐

  1. 为kubernetes-dashboard页面增加过期时间,减少登录次数.

    方法很多,最简单的就是登录后,找到Deployments 服务, 右侧界面会出现kubernetes-dashboard的项目,如果没出现,那么在namespace那里选择全部名称空间. ports: ...

  2. 「luogu3810」陌上花开

    「luogu3810」陌上花开 传送门 三维偏序, \(\text{CDQ}\) 分治板子题. 判重的地方注意一下,别的就都是板子了. 参考代码: #include <algorithm> ...

  3. SpringBoot项目中自定义注解的使用

    1.定义注解接口 @Documented @Retention(RUNTIME) @Target(METHOD) public @interface MyLog {    String value() ...

  4. [Linux] day01——运维

    开发和运维,本质都是提供一种服务. ---------------------------------(最终用户)1 应用2 中间件 服务平台 存储 架构 3 操作系统 硬件驱动4 计算机 网络设备 ...

  5. python字符串和数值操作函数大全(非常全)

    字符串和数值型数字的操作大全 1.反斜杠\的使用规则:一般使用表示续行的操作,可以其他符号相结合组成其他的一些使用符号,转义字符\‘的使用会识别引号,使得字符串中的引号和外面本来的啊引号相区分. (1 ...

  6. MyBatis模糊查询异常: '%${}''读取jdbc属性

    '%${}''总是传root, 后来发现${username}读取了jdbc里面的属性username,于是将jdbc属性名修改,成功

  7. Android问题:ScrollView默认位置不是最顶部最全解决方案

    描述: Scrollview里面嵌套了一个listview ,这是开发中最寻常的一种布局,遇到的问题是:在这个Scrollview页面默认的起始位置不是最顶部,而是listview的底部. 原因: 在 ...

  8. stm32CubeMx工程使用GCC编译

    软件: STM32CubeMx 5.0 GCC编译器 STM32 ST Link Utility 下载器:ST Link V2 1  安装gcc编译器 能编译ARM Cortex M核的GCC编译器下 ...

  9. 【深入】 - AST抽象语法树

    参考: https://segmentfault.com/a/1190000016231512

  10. vue小程序ref和v-for结合使用得到ref数组的一些问题

    项目中需要对每一个民宿里的每一个房间都需要popup弹出层来介绍每一个房间,房间数据都在一个接口(此民宿)上. 主要代码如下: HTML: <view v-for='(item,index) i ...