题目链接:https://nanti.jisuanke.com/t/38228

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≤n≤5×105).

Second line contains nn integers represent the array a (−105≤ai​≤105).

Output

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

样例输入复制

5
1 2 3 4 5

样例输出复制

36

题目定义区间的值为区间之和乘以区间的最小值,要你求出最大的区间值
求出前缀和sum并用线段树维护,再用单调栈求出第i个点之前第一个比他小的点l[i](下标),以及i之后第一个比他小的点r[i](下标)
枚举每个点,如果第i个点非负,区间值即为(sum[r[i]]-sum[l[i]-1])*a[i]
如果第i个点为负数则在[l[i],r[i]]内找到最小的区间和并乘以a[i]即为区间值
#include<iostream>
#include<stack>
using namespace std;
#define maxn 500005
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define ll long long
#define inf 0x3f3f3f3f
int n,l[maxn],r[maxn];
ll a[maxn],b[maxn],pre[maxn],sum[][maxn<<];
void pushup(int rt)
{
sum[][rt]=max(sum[][rt<<],sum[][rt<<|]);
sum[][rt]=min(sum[][rt<<],sum[][rt<<|]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
sum[][rt]=sum[][rt]=pre[l];
return ;
}
int mid=l+r>>;
build(ls);
build(rs);
pushup(rt);
}
ll q1(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)return sum[][rt];
int mid=l+r>>;
ll ans=-inf;
if(L<=mid)ans=max(ans,q1(L,R,ls));
if(R>mid)ans=max(ans,q1(L,R,rs));
return ans;
}
ll q2(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)return sum[][rt];
int mid=l+r>>;
ll ans=inf;
if(L<=mid)ans=min(ans,q2(L,R,ls));
if(R>mid)ans=min(ans,q2(L,R,rs));
return ans;
}
int main()
{
cin>>n;
pre[]=;
for(int i=;i<=n;i++)
{
cin>>a[i];
pre[i]=pre[i-]+a[i];
}
build(,n,);
stack<int>s;
for(int i=;i<=n;i++)
{
while(s.size()&&a[s.top()]>=a[i])s.pop();
if(s.empty())l[i]=;
else l[i]=s.top()+;
s.push(i);
}
while(!s.empty())s.pop();
for(int i=n;i>=;i--)
{
while(s.size()&&a[s.top()]>=a[i])s.pop();
if(s.empty())r[i]=n;
else r[i]=s.top()-;
s.push(i);
}
ll ans=-inf;
for(int i=;i<=n;i++)
{
if(a[i]>=)ans=max(ans,(pre[r[i]]-pre[l[i]-])*a[i]);
else
{
ll maxx,minn;//maxx为[l[i]-1,i-1]的最大前缀和,minn为[i,r[i]]的最小前缀和,最小减最大负的就最多
maxx=q1(max(l[i]-,),max(i-,l[i]),,n,);
minn=q2(i,r[i],,n,);
ans=max(ans,(minn-maxx)*a[i]);
}
}
cout<<ans<<endl;
return ;
}

南昌邀请赛I.Max answer 单调栈+线段树的更多相关文章

  1. 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)

    题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...

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

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

  3. 网络赛 I题 Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...

  4. 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树

    https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...

  5. 2019南昌网络赛-I(单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...

  6. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  7. 洛谷P4198 楼房重建 单调栈+线段树

    正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...

  8. 南昌网络赛 I. Max answer (单调栈 + 线段树)

    https://nanti.jisuanke.com/t/38228 题意给你一个序列,对于每个连续子区间,有一个价值,等与这个区间和×区间最小值,求所有子区间的最大价值是多少. 分析:我们先用单调栈 ...

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

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

随机推荐

  1. c++数据类型漫谈

    在计算机眼里所有数据都是0101,二进制才是物理世界的主宰,c++的数据类型相对其他高级语言是相对较细的,因为是继承C而来,但是c++为什么要设计这么多数据类型呢?因为人类难以理解二进制,这就是数据类 ...

  2. 【C语音基础】printf()用法

    printf() -- 将变量的内容输出到显示器上 四种用法 1.printf("字符串\n"); 2.printf("输出控制符",输出参数); 3.prin ...

  3. orcal - 约束

    数据库约束 1.非空约束 DROP TABLE member PURGE; CREATE TABLE member( mid number , name varchar2(20) not null, ...

  4. 一文读懂PRBS定义、生成办法、作用

    对于眼图测试.误码率和抖动容限测试,最常用的测试码是PRBS,主要有PRBS7.PRBS15.PRBS23和PRBS31.本文主要解释了PRBS的定义,生成方法以及简单应用. PRBS定义 二进制序列 ...

  5. python报以下错误:TypeError: 'int' object is not subscriptable

    原因:数组忘了写下标,数组某项赋值成了 数组对象=数字: 查询其它人的博客,发现仍有其它可能引发此错误,无非是不可以相互操作的对象进行了操作或者是访问对象的方式不对,如:给数字加了下标,对一维数组加了 ...

  6. C#操作Access数据库中遇到的问题(待续)

    (1)在向Access中插入数据时,显示语法错误,后来将生成的sql语句单独拿到Access数据库中运行,能正确插入数据,从网上寻找资料,有人的sql语句正常,但是该语句在Access中运行错误,错误 ...

  7. Unable to docker login through CLI - unauthorized: incorrect username or password

    Unable to docker login through CLI - unauthorized: incorrect username or password To solve it proper ...

  8. Unable to locate appropriate constructor on class报错

    在项目开发中,使用Hibernate里的JPA criteria查询,但是在写完之后使用时,会报错:Unable to locate appropriate constructor on class, ...

  9. 结合之前看的一些东西,阅读RockMQ实战与原理解析笔记

    Topic有多个message queue,消息可以并行的向各个message queue发送,消费者也可以并行的从多个message queue读取消息并消费 clustering模式消费一个top ...

  10. 2017-11-11 Sa Oct How to open a browser in Python

    2017-11-11 Sa Oct How to open a browser in Python python -m webbrowser "http://www.example.com/ ...