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

题目大意:一个区间的值等于该区间的和乘以区间的最小值。给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大值。

样例输入:

5

1 2 3 4 5

样例输出:

36

解题思路:如果序列的值全部为正值的话,可以说很简单,用一个单调栈加前缀和就可以了直接a。但是区间中存在负值,这个问题就变得复杂多了。

首先我们可以用两次单调栈,在O(n)的时间内,对于每个a[i]找到一个最大区间[ l[i] , r[i] ],使得a[i]在这个区间内为最小值。

然后我们便可以枚举每一个a[i],如果a[i]大于0,我们要在区间[ l[i] , r[i] ]内找到一个子区间使得这个区间的和最大,因为这个区间的和越大就可以使得区间的值越大,因为a[i]是区间[ l[i] , r[i] ]的最小值,所以该区间所有值均为正,则子区间的最大和即为[ l[i] , r[i] ]全部数的和,用前缀和便可以求出来了。

但是如果a[i]<0的话,我们就要在[ l[i] , r[i] ]内找到一个子区间使得这个子区间的和最小,这样才能使得区间值最大,我们可以建立两颗线段树,分别维护前缀和的最大值和前缀和的最小值,再在区间[ l[i]-1 , i-1 ]用最大值线段树查找到一个点使得这个点的前缀和最大设最大前缀和为x,再在区间[ i , r[i] ]这个区间内用最小值线段树查找一个点使得这个点的前缀和最小设最小前缀和为y,这样y-x就为区间[ l[i] , r[i] ]内区间和最小的子区间和。

接下来枚举每一个a[i],求出区间值,更新ans就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+;
int n,m,q,l[N],r[N];
ll sum[N],a[N];
stack<ll> st;
ll tr[][N*];
void pushup(int rt){
tr[][rt]=max(tr[][rt<<],tr[][rt<<|]);
tr[][rt]=min(tr[][rt<<],tr[][rt<<|]);
}
void build(int l,int r,int rt){
if(l==r){
tr[][rt]=tr[][rt]=sum[l];
return;
}
int mid=(l+r)/;
build(l,mid,rt*);
build(mid+,r,rt*+);
pushup(rt);
}
ll ask0(int L,int R,int l,int r ,int rt){ //查找[L,R]区间内的最大值
if(L<=l&&R>=r) return tr[][rt];
ll ans=-1e18;
int mid=(l+r)/;
if(mid>=L) ans=max(ans,ask0(L,R,l,mid,rt*));
if(mid<R) ans=max(ans,ask0(L,R,mid+,r,rt*+));
return ans;
}
ll ask1(int L,int R,int l,int r ,int rt){ //查找[L,R]区间内的最小值
if(L<=l&&R>=r) return tr[][rt];
ll ans=1e18;
int mid=(l+r)/;
if(mid>=L) ans=min(ans,ask1(L,R,l,mid,rt*));
if(mid<R) ans=min(ans,ask1(L,R,mid+,r,rt*+));
return ans;
}
int main(){
cin>>n;
for(int i=;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-]+a[i];
}
build(,n,);
for(int i=;i<=n;i++){ //单调栈找左边界
while(st.size()&&a[st.top()]>=a[i])st.pop();
if(st.size()) l[i]=st.top()+;
else l[i]=;
st.push(i);
}
while(st.size()) st.pop();
for(int i=n;i>=;i--){ //单调栈找右边界
while(st.size()&&a[st.top()]>=a[i])st.pop();
if(st.size()) r[i]=st.top()-;
else r[i]=n;
st.push(i);
}
ll ans=-1e18;
for(int i=;i<=n;i++){ //枚举每一个a[i]
int L=l[i],R=r[i];
if(a[i]<){
ll x=ask0(max(L-,),max(i-,),,n,);
if(L==&&x<) x=; //特判L==1的情况
ll y=ask1(i,R,,n,);
ans=max(ans,(y-x)*a[i]);
}else ans=max(ans,(sum[R]-sum[L-])*a[i]);
}
cout<<ans<<endl;
return ;
}

The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)的更多相关文章

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

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

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

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

  3. 2019The Preliminary Contest for ICPC China Nanchang National Invitational

    The Preliminary Contest for ICPC China Nanchang National Invitational 题目一览表 考察知识点 I. Max answer 单调栈+ ...

  4. 计蒜客 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 ...

  5. The Preliminary Contest for ICPC China Nanchang National Invitational

    目录 Contest Info Solutions A. PERFECT NUMBER PROBLEM D. Match Stick Game G. tsy's number H. Coloring ...

  6. The Preliminary Contest for ICPC China Nanchang National Invitational and International Silk-Road Programming Contest

    打网络赛 比赛前的准备工作要做好 确保 c++/java/python的编译器能用 打好模板,放在桌面 A. PERFECT NUMBER PROBLEM #include <cstdio> ...

  7. The Preliminary Contest for ICPC China Nanchang National Invitational I题

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

  8. 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 ...

  9. 2019 The Preliminary Contest for ICPC China Nanchang National Invitational(A 、H 、I 、K 、M)

    A. PERFECT NUMBER PROBLEM 题目链接:https://nanti.jisuanke.com/t/38220 题意: 输出前五个完美数 分析: 签到.直接百度完美数输出即可 #i ...

随机推荐

  1. 前端零基础 --css转换--skew斜切变形 transfor 3d

    前端零基础 --css转换--skew斜切变形 transfor 3d==============重要不紧急! 重要紧急 重要不紧急 不重要紧急 不重要不紧急

  2. 给萌新的Flexbox简易入门教程

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://www.sitepoint.com/flexbox-css-flexible-bo ...

  3. STL源码剖析-vector

    STL(Standard Template Library) C++标准模板库,acm选手一定对它不陌生,除了算法,那几乎是“吃饭的家伙了”.我们使用库函数非常方便,且非常高效(相对于自己实现来说). ...

  4. Git源代码管理

    一. 分支管理 使用 git 进行源代码管理,一般将某个项目的所有分支分为以下几条主线 1. Master 顾名思义,既然名字叫 Master ,那么该分支就是主分支的意思. master 分支永远是 ...

  5. Windows Server 2016-Telnet 简介及安装

    Telnet是基于请求注释(RFC)854的因特网标准程序和协议,该RFC规定了一种在网络上发送和接收未加密的ASCII字符(明文)的方法.Telnet包含两个功能模块:Telnet客户端和Telne ...

  6. 苹果手机对网页上样式为position:fixed的弹窗支持不好的解决办法

    在Web页面上,如果想模拟对话框效果,一般会给div元素添加position:fixed的样式来实现,然后给背景添加一个半透明的遮罩.如: .fixedDiv { position: fixed; t ...

  7. Ruby入坑指南

    1.1 简介 Ruby语言是由松本行弘(Matz)设计,是一门通用的.面向对象的.解释型语言. 1.2 Ruby?RUBY?ruby? 1.Ruby:用来表示编程的语言 2.ruby:是指一个计算机程 ...

  8. Win Server 2008 r2 with SP2装机过程记录

    就这么一个服务器,整整折腾了将近一个星期,才算是折腾完了,今天趁着服务器激活的空闲,赶紧记录下来,以防下次,或者是再有人跟我一样的悲惨经历: 原版出厂光盘下载地址: http://support1.a ...

  9. Java多线程面试

    1.说说进程.线程.协程之间的区别 简而言之,进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程.进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次 ...

  10. VMware安装CentOS7.5

    虚拟机配置: 选择安装方式: 第一行:安装CentOS 7: 第二行:测试这个媒体并安装CentOS 7: 第三行:故障排除: Tips:CentOS 7与CentOS 6网卡名称命名方式有所改变,如 ...