线段树+单调栈+前缀和--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. [GO]conext的使用

    package main import ( "context" "time" "net/http" "fmt" &quo ...

  2. [转]go中的main函数和init函数

    Go里面有两个保留的函数:init函数(能够应用于所有的package)和main函数(只能应用于package main).这两个函数在定义时不能有任何的参数和返回值.虽然一个package里面可以 ...

  3. Linux的磁盘分区(一)

    磁道:track 扇区:sector 磁头:head 柱面:cylinder 每个扇区,512字节 每个磁道划分为63个扇区 逻辑磁头(盘面)数设为255 一个柱面的大小 =255 * 63 * 51 ...

  4. MySQL性能调优与架构设计——第9章 MySQL数据库Schema设计的性能优化

    第9章 MySQL数据库Schema设计的性能优化 前言: 很多人都认为性能是在通过编写代码(程序代码或者是数据库代码)的过程中优化出来的,其实这是一个非常大的误区.真正影响性能最大的部分是在设计中就 ...

  5. Vivado&ISE&Quartus II调用Modelsim级联仿真

    博主一直致力寻找高效的工作方式,所以一直喜欢折腾软件,从刚开始只用软件IDE自带的编辑器,到Notepad++,再到后来的Vim,从用ISE14.7自带的Isim仿真,到发现更好的Modelsim,再 ...

  6. WinExec打开exe文件

    1,WinExec():   WinExec主要运行EXE文件,不能运行其他类型的文件.不用引用特别单元.   原型:UINT WinExec(exePath,ShowCmd)   示例,我想要用记事 ...

  7. CSS3 线性渐变linear-gradient

    CSS3 Gradient 分为 linear-gradient(线性渐变)和 radial-gradient(径 向渐变).为了更好的应用 CSS3 Gradient,需要先了解一下目前的几种现代浏 ...

  8. PostgreSQL递归查询

    原料 --创建组织架构表 create table "Org"( "OrgId" ) primary key, "ParentId" ), ...

  9. eFrameWork学习笔记-eOleDB

    eOleDB是eFrameWork框架下基础的数据访问类,用于执行SQL语句,返回DataTable,分页,返回数据库所有库,库的所有表,表的所有列,Json导入.导出等. HTML: <div ...

  10. mac下MySQL Workbench安装

    参见:http://www.cnblogs.com/macro-cheng/archive/2011/10/25/mysql-001.html 去mysql官网下载社区的.dmg安装包 分别安装: 分 ...