Max answer

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≤ai​≤105).

Output

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

样例输入复制

5
1 2 3 4 5

样例输出复制

36

用单调栈判断以每个值为最小值的最大左边界和右边界。后对对每个值分成负数和正数讨 论取可行区间内的最小或最大值,方法为求前缀和和后缀和,然后用线段树求区间最值。

线段树维护的时候,左区间维护后缀和,右区间维护前缀和,找的时候,在i值左边找后缀,在i值右边找前缀,然后交叉的部分就是满足的区间。

代码:

 //I-线段树+单调栈
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+;
const int inf=0x3f3f3f3f; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 int a[maxn],l[maxn],r[maxn];
ll pre[maxn],beh[maxn],maxl[maxn<<],minl[maxn<<],maxr[maxn<<],minr[maxn<<]; void pushup(int rt)
{
maxl[rt]=max(maxl[rt<<],maxl[rt<<|]);
minl[rt]=min(minl[rt<<],minl[rt<<|]);
maxr[rt]=max(maxr[rt<<],maxr[rt<<|]);
minr[rt]=min(minr[rt<<],minr[rt<<|]);
} void build(int l,int r,int rt)
{
if(l==r){
maxl[rt]=minl[rt]=beh[l];
maxr[rt]=minr[rt]=pre[l];
return ;
} int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
} ll query(int op,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){
if (op==) return maxl[rt];
else if(op==) return minl[rt];
else if(op==) return maxr[rt];
else if(op==) return minr[rt];
} int m=(l+r)>>;
ll ret;
if(op==||op==){
ret=-inf;
if(L<=m) ret=max(ret,query(op,L,R,lson));
if(R> m) ret=max(ret,query(op,L,R,rson));
}
else if(op==||op==){
ret=inf;
if(L<=m) ret=min(ret,query(op,L,R,lson));
if(R> m) ret=min(ret,query(op,L,R,rson));
}
return ret;
} deque<int> deq;//因为是双端队列,所以插的时候要插到头上才能实现栈的功能 int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=;i<=n;i++){
pre[i]=pre[i-]+a[i];
}
for(int i=n;i>=;i--){
beh[i]=beh[i+]+a[i];
}
build(,n,);
for(int i=;i<=n;i++){
while(deq.size()&&a[deq.front()]>=a[i]) deq.pop_front();
if(deq.empty()) l[i]=;
else l[i]=deq.front()+;
deq.push_front(i);
}
deq.clear();
for(int i=n;i>=;i--){
while(deq.size()&&a[deq.front()]>=a[i]) deq.pop_front();
if(deq.empty()) r[i]=n;
else r[i]=deq.front()-;
deq.push_front(i);
}
ll maxx=-inf,ret;
for(int i=;i<=n;i++){
if(a[i]>=){
ret=query(,l[i],i,,n,);
ret+=query(,i,r[i],,n,);
ret=ret-beh[i]-pre[i]+a[i];
ret*=a[i];
// cout<<query(1,l[i],i,1,n,1)<<" "<<query(3,i,r[i],1,n,1)<<endl;
}
else{
ret=query(,l[i],i,,n,);
ret+=query(,i,r[i],,n,);
ret=ret-beh[i]-pre[i]+a[i];
ret*=a[i];
}
maxx=max(maxx,ret);
}
printf("%lld\n",maxx);
}

计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛的更多相关文章

  1. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  2. The Preliminary Contest for ICPC China Nanchang National Invitational I.Max answer单调栈

    题面 题意:一个5e5的数组,定义一个区间的值为 这个区间的和*这个区间的最小值,注意数组值有负数有正数,求所有区间中最大的值 题解:如果全是正数,那就是原题 POJ2796 单调栈做一下就ok 我们 ...

  3. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  4. Max answer(The Preliminary Contest for ICPC China Nanchang National Invitational)

    Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values ...

  5. [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)

    题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...

  6. 洛谷 P4198 楼房重建 线段树维护单调栈

    P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...

  7. 【原创】tyvj1038 忠诚 & 计蒜客 管家的忠诚 & 线段树(单点更新,区间查询)

    最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不懂真的说明最基础的理论没明白 推荐一篇文章http://www.cnblogs.com/liwenchi/ ...

  8. [计蒜客T2238]礼物_线段树_归并排序_概率期望

    礼物 题目大意: 数据范围: 题解: 这题有意思啊($md$卡常 直接做怎么做? 随便上个什么东西,维护一下矩阵乘和插入,比如说常数还算小的$KD-Tree$(反正我是没见人过过 我们漏掉了一个条件, ...

  9. [BZOJ 2957]楼房重建(THU2013集训)(线段树维护单调栈)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2957 分析: 根据题意,就是比较斜率大小 只看一段区间的话,那么这段区间能看见的楼房数量就是这 ...

随机推荐

  1. 【转载】C#中List集合使用LastOrDefault方法查找出最后一个符合条件的元素

    在C#的List集合中,FirstOrDefault方法一般用来查找List集合中第一个符合条件的对象,如果未查到则返回相应默认值.其实如果要查找最后一个符合条件的List集合元素对象,可以使用Las ...

  2. JavaScript克隆数组

    /** * 克隆数组 * @param arr */ function cloneArray(arr){ var _arr=[]; for(var i=0;i<arr.length;i++){ ...

  3. java中的参数传递

    Java中只有传值调用(值传递),没有传址调用(址传递或者引用传递).所以在java方法中改变参数的值是不会改变原变量的值的,但为什么改变引用变量的属性值却可以呢?请看下面的解答. java中的数据类 ...

  4. MongoDB 基本概念

    MongoDB和关系型数据库的对应关系 关系数据库 MongoDB 数据库   database 数据库   database 表格  table 集合  collection 行  row 文档  ...

  5. http请求的几种content-type

    1. 2.二进制文件 3.form-data 数据:a=1 总结: 1.对于我自己的写的服务来说,只要是raw,接收到的都是二进制字符: 2.如果是urlencode,接收到的是拼接的字符串(和使用p ...

  6. 大数据系列文章-Hadoop基础介绍(一)

    Hadoop项目背景简介 2003-2004年,Google公开了部分GFS个Mapreduce思想的细节,以此为基础Doug Cutting等人用了2年的业余时间,实现了DFS和Mapreduce机 ...

  7. 深入理解java虚拟机(linux与jvm内存关系)

    本文转载自美团技术团队发表的同名文章 https://tech.meituan.com/linux-jvm-memory.html 一, linux与进程内存模型 要理解jvm最重要的一点是要知道jv ...

  8. Linux操作系统的进程管理和作业管理

    Linux操作系统的进程管理和信号 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.lsof命令详解 1>.lsof概述 list open files查看当前系统文件的工 ...

  9. zsh of kali

    首先安装zsh: # apt-get update # apt-get install zsh -y 然后直接使用仓库脚本: # sh -c "$(wget https://raw.gith ...

  10. java 获取最近7天 最近今天的日期

    private static Date getDateAdd(int days){ SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-d ...