线段树+单调栈+前缀和--2019icpc南昌网络赛I

Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values in the interval, multiplied by the smallest value in the interval.

Now she is planning to find the max value of the intervals in her array. Can you help her?

Input

First line contains an integer n(1 \le n \le 5 \times 10 ^5n(1≤n≤5×105).

Second line contains nn integers represent the array a (-10^5 \le a_i \le 10^5)a(−105≤a**i≤105).

Output

One line contains an integer represent the answer of the array.

样例输入复制

5
1 2 3 4 5

样例输出复制

36

思路

算前缀和,以每个a_i为最低点,用单调栈求出a_i的所能影响的范围

若a_i>=0,则maxR-minL

若a_i<0,则minR-min(0,maxL)

minR,和maxL用线段树查询,线段树构建:以前缀和为底,找出范围内的最值

代码

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <sstream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <queue>
#include <iomanip>
#include <stack> using namespace std; typedef long long LL;
const int INF = 0x3f3f3f3f;
const int N = 5e5+5;
const int MOD = 1e9 + 9;
const double pi = 3.1415926; #define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
#define F(i, l, r) for(int i = l;i <= (r);++i)
#define RF(i, l, r) for(int i = l;i >= (r);--i) LL a[N], sum[N], tree_min[N << 2], tree_max[N << 2];
void build(int l, int r, int rt)
{ if(l == r)
{
tree_min[rt] = tree_max[rt] = sum[l];
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
tree_max[rt] = max(tree_max[rt << 1], tree_max[rt << 1 | 1]);
tree_min[rt] = min(tree_min[rt << 1], tree_min[rt << 1 | 1]);
} LL Query_max(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
return tree_max[rt];
int m = (l + r) >> 1;
LL ans = -1e18;
if(L <= m)
ans = max(ans, Query_max(L, R, lson));
if(R > m)
ans = max(ans, Query_max(L, R, rson));
return ans;
} LL Query_min(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
return tree_min[rt];
int m = (l + r) >> 1;
LL ans = INF;
if(L <= m)
ans = min(ans, Query_min(L, R, lson));
if(R > m)
ans = min(ans, Query_min(L, R, rson));
return ans;
} stack<int> s;
LL rig[N], lef[N];
int main()
{
int n;
cin >> n;
F(i, 1, n)
{
cin >> a[i];
sum[i] = sum[i - 1] + a[i];
}
build(1, n, 1);
F(i, 1, n)
{
while(!s.empty() && a[s.top()] > a[i]) {rig[s.top()] = i - 1;s.pop();}
s.push(i);
}
while(!s.empty())
{
rig[s.top()] = n;
s.pop();
}
RF(i, n, 1)
{
while(!s.empty() && a[s.top()] > a[i]) {lef[s.top()] = i + 1;s.pop();}
s.push(i);
}
while(!s.empty())
{
lef[s.top()] = 1;
s.pop();
}
LL ans = -1e18, t;
F(i, 1, n)
{
if(a[i] > 0)
t = sum[rig[i]] - sum[lef[i] - 1];
else
t = Query_min(i, rig[i], 1, n, 1) - max(0ll, Query_max(lef[i], i, 1, n, 1));
//cout << Query_min(i, rig[i], 1, n, 1) << " " << max(0ll, Query_max(lef[i], i, 1, n, 1)) << endl;
ans = max(ans, t * a[i]);
}
cout << ans << endl;
return 0;
}

线段树+单调栈+前缀和--2019icpc南昌网络赛I的更多相关文章

  1. 牛客多校第四场sequence C (线段树+单调栈)

    牛客多校第四场sequence C (线段树+单调栈) 传送门:https://ac.nowcoder.com/acm/contest/884/C 题意: 求一个$\max {1 \leq l \le ...

  2. Codeforces 781E Andryusha and Nervous Barriers 线段树 单调栈

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF781E.html 题目传送门 - CF781E 题意 有一个矩形,宽为 w ,高为 h .一开始会有 w 个 ...

  3. 洛谷P4425 转盘 [HNOI/AHOI2018] 线段树+单调栈

    正解:线段树+单调栈 解题报告: 传送门! 1551又是一道灵巧连题意都麻油看懂的题,,,,所以先解释一下题意好了,,,, 给定一个n元环 可以从0时刻开始从任一位置出发 每次可以选择向前走一步或者在 ...

  4. Codeforces 1175F - The Number of Subpermutations(线段树+单调栈+双针/分治+启发式优化)

    Codeforces 题面传送门 & 洛谷题面传送门 由于这场的 G 是道毒瘤题,蒟蒻切不动就只好来把这场的 F 水掉了 看到这样的设问没人想到这道题吗?那我就来发篇线段树+单调栈的做法. 首 ...

  5. 2019icpc南昌网络赛_I_Yukino With Subinterval

    题意 给定一个序列,两种操作,单点修改,询问区间\([l,r]\)值域在\([x,y]\)范围内的连续段个数. 分析 原数组为\(a\),构造一个新的数组\(b\),\(b[i]=(a[i]==a[i ...

  6. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  7. cdqz2017-test10-rehearsal(CDQ分治&可持久化线段树&单调栈)

    题意: 给出n个三元组 e[i]=(si,ti,wi) 第i个三元组的价值为 Σ w[j] ,j 满足以下4个条件: 1.j<i 2.tj<ti 3.sj<si 4.不存在j< ...

  8. BZOJ3521 [Poi2014]Salad Bar 【线段树 + 单调栈】

    题目链接 BZOJ3521 题解 容易想到用前缀和搞 如果我们令\(p\)为\(1\),\(j\)为\(-1\),记前缀和为\(s[i]\) 我们就是要找到一段区间\([l,r]\),使得 \[\fo ...

  9. sequence(线段树+单调栈) (2019牛客暑期多校训练营(第四场))

    示例: 输入: 31 -1 11 2 3 输出: 3 题意:求最大的(a区间最小值*b区间和) 线段树做法:用单调栈求出每个数两边比b数组大的左右边界,然后用线段树求出每段区间的和sum.最小前缀ls ...

随机推荐

  1. UVa 12186 Another Crisis (DP)

    题意:有一个老板和n个员工,除了老板每个员工都有唯一的上司,老板编号为0,员工们为1-n,工人(没有下属的员工),要交一份请愿书, 但是不能跨级,当一个不是工人的员工接受到直系下属不少于T%的签字时, ...

  2. BCD码转换为十进制或者十进制转为BCD码

    BCD码其实就是之前在数字电路中说的 用4位二进制数值 来表示一个0-9中的数字,例如: 0000=0 0001=1 0010=2 0011=3也就是说如果把一个数字作为一个BCD码,例如: 11 2 ...

  3. git ssh创建秘钥

    git是分布式的代码管理工具,远程的代码管理是基于ssh的,所以要使用远程的git则需要ssh的配置. github的ssh配置如下: 一 . 设置git的user name和email: $ git ...

  4. C++ 数据封装和抽象

    C++ 数据抽象 数据抽象是指,只向外界提供关键信息,并隐藏其后台的实现细节,即只表现必要的信息而不呈现细节. 数据抽象是一种依赖于接口和实现分离的编程(设计)技术. 让我们举一个现实生活中的真实例子 ...

  5. mongodb-win32-i386-3.0.6 使用常见错误

    1.Error parsing YAML config file: yaml-cpp: error at line 3, column 28: unknown escape character: m ...

  6. python int函数转换浮点型字符串的坑???

    python中的int函数可以将数字或字符串转换为整型数字类型,具体功能就不提了 最近发现一个问题,对于字符串'1.1'之类的,int转换的时候会报异常,这是为什么,个人感觉直接转换成1不就行了,干嘛 ...

  7. Java对象和XML转换

    有时候,我们需要把Java对象转换成XML文件.这时可以用JAXB来实现.(JDK1.6及以后的版本无需导入依赖包,因为已经包含在JDK里了) 假如某个公司有许多部门,每个部门有许多职员,我们可以这样 ...

  8. 咏南中间件当作WEB SERVER使用方法

    咏南中间件当作WEB SERVER使用方法 1)开启咏南中间件 2)浏览器打开http://localhost:5566/web?page=echo.html

  9. 【C++】C++中的操作符重载

    C++中的操作符重载使得对于类对象的操作更加方便和直观,但是对于各种操作符重载的规则以及语法形式,一直以来都是用到哪一个上stackoverflow上查找,在查找了四五次之后,觉得每次麻烦小总结一下. ...

  10. Unity&C# SingerMonoManager泛型单例

    管理各种管理器 ///为什么需要单例 ///单例模式核心在于对于某个单例类,在系统中同时只存在唯一一个实例,并且该实例容易被外界所访问: ///避免创建过多的对象,意味着在内存中,只存在一个实例,减少 ...