题目链接: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 ;
}

最新文章

  1. python之路十二
  2. 【iOS Instrument性能优化集】
  3. Lind.DDD.UoW~方法回调完成原子化操作
  4. flume安装及配置介绍(二)
  5. uart串口的调试学习
  6. FIR滤波器(1)- 基础知识
  7. asp.net 获取客户机IP地址
  8. 洛谷P1117 棋盘游戏
  9. js、jquery、css使用过程中学到的一些方法技巧
  10. UIImageView 的contentMode属性应用
  11. 电脑打不开网页,使用dns优化下就可以了。
  12. 面试题-浅谈JavaScript中的This指向问题
  13. .net Core+Dapper MySQL增删改查
  14. Java try-cath-finally异常
  15. vue中遇到的问题:Error: Cannot find module &#39;chalk&#39;
  16. [总结] 动态DP学习笔记
  17. GDPR 和个人信息保护的小知识
  18. android矩阵详解
  19. eclipse没有server选项解决方法
  20. php脚本超时 结束执行代码

热门文章

  1. Opencv与Qt (一)之运行测试读取图片
  2. Storm实现实时大数据分析(storm介绍,与Hadoop比较,)
  3. nginx配置多个域名
  4. Python爬虫与数据分析之模块:内置模块、开源模块、自定义模块
  5. Mysql 创建用户授权
  6. DP问题
  7. mybatis运行原理学习
  8. RuntimeError: module compiled against API version 0xb but this version of numpy is 0xa
  9. UI设计篇&#183;入门篇&#183;绘制简单自定义矩形图/设置按钮按下弹起颜色变化/设置图形旋转
  10. Python序列化操作与反序列操作