题目链接: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. mass

    @python青岛qq群 1.爬取豆瓣,登录一次爬取后再循环就退出登录,抓不到了: 2.用requests.session试试,只要session对象不释放,就能记住登录状态的cookie: 3.se ...

  2. Python12(接口继承,子类调用父类,多态)

    接口继承: 基类不用实现内部逻辑,只是为了规范子类,可以用abc模块中以添加装饰器的方式实现 import abc class All_file(metaclass=abc.ABCMeta): @ab ...

  3. asp.net ajax get 调用(和post不一样,直接返回json才行,否则报错;post不能返回json)

    <script type="text/javascript" > $(document).ready(function () { $('#Label1').click( ...

  4. DLL 函数中使用结构体指针作函数参数(C# 调用 C++ 的 DLL)

    存在的问题: 问题1:C++ 与 C# 同样定义的结构体在内存布局上有时并不一致: 问题2:C# 中引入了垃圾自动回收机制,其垃圾回收器可能会重新定位指针所指向的结构体变量. 解决方案: 问题1方案: ...

  5. 排序大集合java

    今日面试被问到排序问题,发现自己的不足,特来查漏补缺: 首先是各大排序算法的总结表 排序算法大合集  排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 稳定性 冒泡排序 Ο(n2) Ο(n) ...

  6. linux 之网络命令

    write 给用户发消息,用户必须在线,以ctrl+d保存结束 语法: write 用户 wall发广播信息(write all)  语法:wall 信息 mail 查看发送电子邮件 发送语法 : m ...

  7. 在java程序当中怎么获取一个文件的路径

    在java程序当中怎么获取一个文件的路径? * 当这个文件在类路径下的时候(在src/bin目录下的时候): String absolutePath = Thread.currentThread(). ...

  8. jQuery之位置坐标图形相关方法

    jQuery实例方法-位置图形 位置坐标图形大小相关方法: .offset() .position() .scrollTop() ..scrollLeft() .width()..height() . ...

  9. C语言典型编程2

    关于C的一些小而精的编程,适合希望提升编程能力的初学者学习:关键编程也就几句,但思维可以迁移到其他编程语言.同一问题,算法多种. //任意整数的任意次方取后3位(算数取位)#include<st ...

  10. mysql判断表里面一个逗号分隔的字符串是否包含单个字符串、查询结果用逗号分隔

    1.mysql判断表里面一个逗号分隔的字符串是否包含单个字符串 : FIND_IN_SET select * from tablename where FIND_IN_SET(传的参数,匹配字段) 例 ...