线段树+单调栈+前缀和--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. BUG记忆

      保留两位小数 <fmt:formatNumber value="${list.avgAssessment}" pattern="#.00#"/> ...

  2. CLOB 和 BLOB

    An SQL CLOB is a built-in type that stores a Character Large Object as a column value in a row of a ...

  3. window.location 对象

    http://www.home.com:8080/windows/location/page.html?ver=1.0&id=timlq#love 1, window.location.hre ...

  4. c+内存管理机制

    内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的 检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存 ...

  5. Android-应用安装/替换/卸载/广播监听

    在上一篇博客Android-开关机的广播,中介绍了,如何订阅接收者,去接收系统发送的开机/关机广播, 而这篇博客是订阅接收者 去接收应用的(安装/替换/卸载) 三种广播 订阅 接收者 去接收 应用的 ...

  6. java中的软引用,弱引用,虚引用

    http://zh.wikipedia.org/wiki/%E5%BC%B1%E5%BC%95%E7%94%A8 有些语言包含多种强度的弱引用.例如Java,在java.lang.ref[1]包中定义 ...

  7. c++中的隐藏及重载、重写与隐藏的区别

    c/c++中的隐藏  举个栗子 class A { public : void fun1(int a, int b) { cout<<"abcd"<<end ...

  8. solr-4.10.2版本使用tomcat7部署

    当前版本仅限于solr-4.10.2版本.默认环境使用的是jdk1.7,tomcat7.环境自己配置.网上一堆堆的. 1.下载相应的文件(solr-4.10.2.zip). 官网地址:http://l ...

  9. 多次grep 没有看到输出

    tail -f xxx.log | grep aaaa | grep bbbb 发现没有日志输出 但log中的那条记录包含aaaa 和 bbbb,就是说tail  -f xxx.log | grep ...

  10. ADO.NET操作SQL Server:数据库操作类(已封装)

    1.增.删.改通用方法 /// <summary> /// 增.删.改通用方法 /// </summary> /// <param name="commandT ...