POJ2796---Feel Good(前缀和+单调栈维护)

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

Source

Northeastern Europe 2005

维护一个递减的单调栈+预处理前缀和

/*************************************************************************
    > File Name: poj2796.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年05月07日 星期四 19时20分20秒
 ************************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>

using namespace std;

const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

static const int N = 100100;
stack <PLL> st;
int val[N];
LL sum[N];
int l[N];
int r[N];

int main() {
    int n;
    while (~scanf("%d", &n)) {
        sum[0] = 0;
        for (int i = 1; i <= n; ++i) {
            scanf("%d", &val[i]);
            sum[i] = sum[i - 1] + val[i];
            l[i] = r[i] = i;
        }
        while (!st.empty()) {
            st.pop();
        }
        for (int i = n; i >= 1; --i) {
            if (st.empty()) {
                st.push(make_pair(val[i], i));
            }
            else {
                while (!st.empty()) {
                    PLL u = st.top();
                    if (val[i] >= u.first) {
                        break;
                    }
                    st.pop();
                    l[u.second] = i + 1;
                }
                st.push(make_pair(val[i], i));
            }
        }
        while (!st.empty()) {
            PLL u = st.top();
            st.pop();
            l[u.second] = 1;
        }
        for (int i = 1; i <= n; ++i) {
            if (st.empty()) {
                st.push(make_pair(val[i], i));
            }
            else {
                while (!st.empty()) {
                    PLL u = st.top();
                    if (val[i] >= u.first) {
                        break;
                    }
                    st.pop();
                    r[u.second] = i - 1;
                }
                st.push(make_pair(val[i], i));
            }
        }
        while (!st.empty()) {
            PLL u = st.top();
            st.pop();
            r[u.second] = n;
        }
        LL ans = -1;
        int L, R;
        for (int i = 1; i <= n; ++i) {
            int y = r[i];
            int x = l[i];
            if (ans < (sum[y] - sum[x - 1]) * val[i]) {
                ans = (sum[y] - sum[x - 1]) * val[i];
                L = x;
                R = y;
            }
        }
        printf("%lld\n", ans);
        printf("%d %d\n", L, R);
    }
    return 0;
}
时间: 2025-01-15 09:26:46

POJ2796---Feel Good(前缀和+单调栈维护)的相关文章

CF1137E Train Car Selection(单调栈维护凸函数)

首先本题的关键是一次性加0操作只有第一个0是有用的.然后对于1 k操作,其实就是把之前的所有数删除.对于其他的情况,维护一次函数的和,将(i,a[i])看成平面上的一个点,用单调栈维护一下. #include<bits/stdc++.h> using namespace std; const int N=3e5+7; #define int long long typedef pair<int,int>pii; int n,k,b,Q,top; pii st[N]; long do

【单调栈维护连续区间】2019.1.18模拟赛T2 浇花

这道题是一道单调栈的题 1 题目描述 2 JDFZ在餐厅门前种了一排nn棵花,每棵花都有一个高度.浇花大爷会枚举所有的区间,然后从区间中找出一个高度最矮的花进行浇水.由于浇花大爷浇完水之后就精疲力竭了,所以请你帮助他计算每棵花都被浇了几次水. 3 4 输入格式 5 第一行一个整数nn. 第二行nn个整数,分别表示每棵花的高度. 6 7 输出格式 8 一行nn个整数用空格隔开,分别表示每棵花被浇了几次水. 9 10 样例一 11 input 12 3 13 1 3 5 14 output 15 3

Lost My Music:倍增实现可持久化单调栈维护凸包

题目就是求树上每个节点的所有祖先中(ci-cj)/(dj-di)的最小值. 那么就是(ci-cj)/(di-dj)的最大值了. 对于每一个点,它的(ci,di)都是二维坐标系里的一个点 要求的就是祖先节点的所有点与目前节点连线的最小斜率 比较容易想到单调栈优化,像斜率优化dp一样 但是关键是本题在树上,会有很多麻烦的操作. 当搜到某一个儿子时可能会弹很多栈,而回溯的过程中需要把它们加回来. 如果暴力执行的话,会在蒲公英图退化为n2. 考虑优化:现在的关键就是在于在一个元素可能被弹栈/还原多次的情

HDU 5033 (单调栈维护凸包) Building

题意: 一个人在x轴上,他的左右两侧都有高楼,给出楼的横坐标Xi和高度Hi还有人的位置pos,求人所能看到的天空的最大角度. 分析: 将建筑物和人的位置从左到右排序,对于每个位置利用栈求一次人左边建筑物的凸包,找到一个最小的角度,然后对称一下,再找一个右边的建筑物的最小角度,两个角度加起来就是答案. 将人左边的建筑物从左到右扫描,下面两种情况会出栈: 栈顶元素楼高小于等于当前扫描到的楼高,因此这是一个单调的栈 栈顶两个楼顶所在直线的斜率 小于 栈顶的楼顶和当前楼顶所在直线的斜率(这里的斜率指的是

poj2599 单调栈维护最大连续矩形面积

这个题就是给你一串连续的矩形, 每个矩形的宽度为1, 高度给定, 选定连续的一串矩形, 其高度是所有矩形高度中的最小值,宽度为选定的, 问怎么选能使矩形的面积最大?我们以一个矩形为中心,并设这个矩形的高度最小, 分别向两边延生, 那么此时的最大面积就是a[i] * (R[i]-l[i]+1), 代码如下: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream>

POJ2796Feel Good[单调栈]

Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13376   Accepted: 3719 Case Time Limit: 1000MS   Special Judge Description Bill is developing a new mathematical theory for human emotions. His recent investigations are dedicated

单调队列单调栈

单调队列单调栈 Tags:数据结构 更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1041449 一.概述 单调队列单调栈是很基础的数据结构,常用来优化一些东西比如说优化DP 那么大概意思就是在栈或队列中按照某关键字单调维护信息,从而实现一些功能 其实很久之前接触过单调队列和单调栈,但一直没有刷题,趁这两天被LCT弄晕的时候复习下这些 先看题 二.题单 普及- [x] P1886 滑动窗口 https://www.luogu.org/problemnew/

[Codeforces Round #622 (Div. 2)] - C2. Skyscrapers (hard version) (单调栈)

[Codeforces Round #622 (Div. 2)] - C2. Skyscrapers (hard version) (单调栈) C2. Skyscrapers (hard version) time limit per test 3 seconds memory limit per test 512 megabytes input standard input output standard output This is a harder version of the probl

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 单调栈

Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 问题 传送门 我是参考了这篇题解传送门,然后按着思路做出了的(但大佬题解中的sumr[]数组操作我没看懂,然后自己改了改). 摘抄: 维护峰值最优 找左右边的第一个比自己小的元素,维护前缀和,找最大的峰值 l[i]:用单调栈维护左边第一个比它小的数 r[i]:用单调栈维护右边第一个比它小的数 suml[i]:左边的前缀和 sumr[i]:右边的前缀和 然后遍历一遍数组,找到