题目链接: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. javaweb + websocket实现客户端

    最近需要完成一个javaweb项目,但是没有和数据库连接而是通过websocket通讯实现和服务器端数据交互.我搜了好多,网上大部分都是通过页面websocket连接本地服务器或连接异地服务器,但是这 ...

  2. 纯手写springIOC

    大家好啊- 那么今天来带大家写一下spring的ioc. 其实也很简单,首先我们明白两点,java解析xml和java的反射机制,因为ioc就是主要是基于这两个来实现,今天只是简单的来大家实现下. 废 ...

  3. weblogic patch log显示

    如何在WebLogic 12.1.3 版本的 server log 中显示 opatch 的补丁信息? 打补丁  patch 23558563 之后. 需要在 JAVA_OPTIONS 中添加如下参数 ...

  4. solr8.0 ik中文分词器的简单配置(二)

    下载ik分词器,由于是solr8.0,一些ik分词器版本可能不兼容,以下是个人亲测可行的版本 ik分词器下载 然后将解压出来的两个jar包放到以下路径: 其它的三个文件放到以下路径: 如果没有clas ...

  5. Android Studio教程10-Intent的详细使用

    目录 1. Intent启动器 1.1. Intent的用途 1. 启动Activity 3. 传递广播 1.2. Intent类型 1.显示Intent 2.隐式Intent 2. 构建Intent ...

  6. Redis 由浅入深

    1.redis是什么? redis是nosql(也是个巨大的map) 单线程,但是可处理1秒10w的并发(数据都在内存中) 使用java对redis进行操作类似jdbc接口标准对mysql,有各类实现 ...

  7. js 学习之路9:运算符

    1. 算数运算符 运算符 描述 例子 结果 + 加 x=y+2 x=7 - 减 x=y-2 x=3 * 乘 x=y*2 x=10 / 除 x=y/2 x=2.5 % 求余数 (保留整数) x=y%2 ...

  8. Bootstrap -- 插件: 按钮状态、折叠样式、轮播样式

    Bootstrap -- 插件: 按钮状态.折叠样式.轮播样式 1. 按钮(Button)插件:可以添加进一些交互,比如控制按钮状态. 如需向按钮添加加载状态,只需要简单地向 button 元素添加 ...

  9. 5G来了,中国移动能力开放平台的NFV,支持面向5G的演进,已经具备初期商用条件!

    近日互联网招聘平台发布的<2019春招旺季人才趋势报告>显示,“新新职业”人才受到企业追捧: 5G相关人才需求大幅增长,5G工程师平均招聘月薪达1.39万元,同比增长12.2%.其中,光传 ...

  10. casbin-权限管理

    概要 权限管理几乎是每个系统或者服务都会直接或者间接涉及的部分. 权限管理保障了资源(大部分时候就是数据)的安全, 权限管理一般都是和业务强关联, 每当有新的业务或者业务变化时, 不能将精力完全放在业 ...