就是求区间和与区间最小值的积的最大值 但是a[i]可能是负的 这就很坑 赛后看了好多dalao的博客 终于a了

这个问题我感觉可以分为两个步骤

第一步是对于每个元素 以它为最小值的最大区间是什么

第二步是找出来在这个区间里面 最大的连续和多少

那么我们怎么找到第一步这个最大区间呢

可以先找这个元素左边第一个比他小的值的下标 和右边第一个比他小的值的下标 这两个下标确定了 最大区间就确定了

怎么找这个下标呢 暴力的话时间复杂度太高 是n^2 需要使用单调栈:

单调栈 顾名思义就是元素都是单调递增或者递减的栈 至于它有什么作用 接着往下看

假如有一个数组a:   3 5 1 6 2

用数组 L 表示a数组里的每一个元素 从自身位置 向左 第一个比它小的元素的位置

那么L就应该是: 0 1 0 3 3 (这里为了方便表示 我让a数组的下标从1开始标记 这样L数组里面 0 就表示左边的数都比他大 1 就表示第一个数比他小 以此类推)

那么我们怎么利用单调栈实现呢?

先将 a[0]赋值为一个极小值 -0x7ffffff,然后将0入栈

对于数组a的每一个元素 进行如下语句:

while(a[S.top()]>=a[i])
S.pop();
l[i] = S.top();
S.push(i);

while语句 保证了栈里面的数据是单调递减的

看不明白没有关系 让我们模拟一下:
i==1时 a[S.top]=a[0]=-0x7ffffff 不进入while循环

所以L[1]=0;

将1入栈 此时的栈:0 1(实际上我们比较的是a[i] 所以逻辑上来讲 此时的栈:a[0] a[1] 也就是 -0x7ffff 3 因为我们需要用到左边的下标值 所以是将下标入栈 这样既可以访问到下标所对应的值 也可以访问下标)

i==2时,a[S.top]=a[1]=3 小于5 还是不进入while循环

L[2]=S.top()=1

将2入栈 此时的栈:0 1 2(-0x7ffff  3  5 )

i==3时,a[S.top]=a[2]=5 大于1

S.pop(),a[S.top]=a[1]=3还是大于1

S.pop(),a[S.top]=a[0]=-0x7ffffff 小于1 结束循环

所以L[3]=0

将3入栈 此时的栈:0 3(-0x7ffff  1)

.........

以此类推

逻辑上栈中的元素(a[i])始终是递减的

这样我们就通过以此循环求出了L数组 也就是找到了之前说的 最大区间的左边界 找右边界也是一样的思路,只是循环的方向不同

好了现在我们完成了第一步 要进行第二步 也就是找每个区间里面的最大连续和(如果a[i]<0的话需要找最小连续和)

如果a[i]均为非负的话就很简单了 肯定是区间越长 连续和越大 但问题是a[i]是可以有负数的

那就需要分情况讨论了

我们可以开4个数组 lmax lmin rmax rmin

lmax 和 rmax 用来记录最大连续和的区间的左右下标

lmin 和 rmin 记录最小的和的左右下标

怎么更新这四个数组呢?

for(i=;i<=n;i++)
{
if(s[i-]-s[lmin[i-]-]>)
lmin[i]=i;
else
lmin[i]=lmin[i-];
if(s[i-]-s[lmax[i-]-]<)
lmax[i]=i;
else
lmax[i]=lmax[i-];
}

s[i]是前i项的和

看代码很容易理解 如果前面几项的和是正的 那就不要他 让lmin[i]=i 如果是负的 那么加上他 这样连续和就会变小

rmax和rmin只需要倒着更新就行

最后别忘了 这四个数组必须是在L数组和R数组的范围内的 相当于第一步是第二步的限制条件:

    if(a[i]<)
{
ll=max(l[i]+,lmin[i]);
rr=min(r[i]-,rmin[i]);
}
else
{
ll=max(l[i]+,lmax[i]);
rr=min(r[i]-,rmax[i]);
}

完整ac代码:

#include<bits/stdc++.h>

using namespace std;

long long i,n,ll,rr,s[],a[],lmin[],lmax[],rmin[],rmax[],l[],r[],ans;
stack<long long> S; int main()
{
cin>>n;
for(i=;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-]+a[i];
}
ans=a[]*a[];
S.push();
a[]=-0x7fffff;
a[n+]=-0x7fffff-;
for(i=;i<=n;i++)
{
while(a[S.top()]>=a[i])
S.pop();
l[i] = S.top();
S.push(i);
}
while(S.size())
S.pop();
S.push(n+);
for(i=n;i>=;i--)
{
while(a[S.top()]>=a[i])
S.pop();
r[i]=S.top();
S.push(i);
}
lmin[]=;
lmax[]=;
rmin[n]=n;
rmax[n]=n;
for(i=;i<=n;i++)
{
if(s[i-]-s[lmin[i-]-]>)
lmin[i]=i;
else
lmin[i]=lmin[i-];
if(s[i-]-s[lmax[i-]-]<)
lmax[i]=i;
else
lmax[i]=lmax[i-];
}
for(i=n-;i>=;i--)
{
if(s[rmin[i+]]-s[i]>)
rmin[i]=i;
else
rmin[i]=rmin[i+];
if(s[rmax[i+]]-s[i]<)
rmax[i]=i;
else
rmax[i]=rmax[i+];
}
for(i=;i<=n;i++)
{
if(a[i]<)
{
ll=max(l[i]+,lmin[i]);
rr=min(r[i]-,rmin[i]);
}
else
{
ll=max(l[i]+,lmax[i]);
rr=min(r[i]-,rmax[i]);
}
ans=max(ans,a[i]*(s[rr]-s[ll-]));
}
cout<<ans; }

icpc 南昌邀请赛网络赛 Max answer的更多相关文章

  1. 2019 ICPC南昌邀请赛网络赛比赛过程及题解

    解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...

  2. icpc 南昌邀请赛网络赛 Subsequence

    题目链接:https://nanti.jisuanke.com/t/38232 就是判断输入是不是子序列 没想到贡献了将近十几次罚时..........可以说是菜的真实了 用cin cout超时了 改 ...

  3. 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR

    说明 \(\oplus x​\)为累异或 $ x^{\oplus(a)}​$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...

  4. 南昌邀请赛网络赛 D.Match Stick Game(dp)

    南昌邀请赛网络赛 D.Match Stick Game 题目传送门 题目就会给你一个长度为n的字符串,其中\(1<n<100\).这个字符串是一个表达式,只有加减运算符,然后输入的每一个字 ...

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

  6. POJ-2796 & 2019南昌邀请赛网络赛 I. 区间最大min*sum

    http://poj.org/problem?id=2796 https://nanti.jisuanke.com/t/38228 背景 给定一个序列,对于任意区间,min表示区间中最小的数,sum表 ...

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

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

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

  9. 2019南昌邀请赛网络赛:J distance on the tree

    1000ms 262144K   DSM(Data Structure Master) once learned about tree when he was preparing for NOIP(N ...

随机推荐

  1. 【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)

    万字长文,干货满满. 是数据结构而非类型 很多文章都会说,redis支持5种常用的数据类型,这其实是存在很大的歧义.redis里存的都是二进制数据,其实就是字节数组(byte[]),这些字节数据是没有 ...

  2. 1.5准备CentOS和Nginx环境「深入浅出ASP.NET Core系列」

    准备CentOS 1.1虚拟机 CentOS的安装这里使用vmware workstation 14来做虚拟机,当然你也可以用Oracle的虚拟机或者不用虚拟机,使用云服务或者使用双系统,不是什么大问 ...

  3. 兼容小程序的canvas画图组件jmGraph

    基于CANVAS的简单画图组件让你用类似于dom的方式,在canvas上画图,感觉会不会很爽. 主页:http://graph.jm47.com/示例:http://graph.jm47.com/ex ...

  4. DS标签控件文本解析格式

    DS标签控件使用DSL文本渲染引擎,支持DSL引擎代码.目前支持代码如下: <b>粗体</b> 以粗体显示 <i>斜体</i> 以斜体显示 <u& ...

  5. es6 generator函数

    es6 新增了Generator函数,一种异步编程的解决方案 回顾一下,es6 提供了新的遍历方法,for of ,适用于各种数据集合,统一了遍历操作,原生支持for of 集合的数据集合有.数组,字 ...

  6. 升级WIN10 (9879)后IE无响应的解决办法

    身为程序猿,当然有了新系统就要尝尝鲜,有WIN8时,哥是朋友圈第一个用的,有WIN8.1时哥也是第一个升级的. 现在WIN10来了,当然也得赶紧尝尝鲜.直接下载了 9879版的预览版本安装. 要说WI ...

  7. BestSync多终端文件资料同步利器

    分享一款多终端文件同步的强力软件,windows下使用. 我这里的多终端意思是,多台电脑.移动存储.云端. 就我个人而言,实用性在于移动硬盘和电脑上都有的文件,比如保存项目资料,电脑上需要编辑,有时外 ...

  8. 长图的展开与收起(Android)

    前言: 在app的文章中,经常会夹杂着一些特别长的长图.在阅读的时候需要滑动很久才能看图片下方的文字,因此对于长图只展示图片上面一部分,并且可以展开这个功能是很重要的. 效果: 基本思路: 利用sca ...

  9. RowKey设计之单调递增行键/时序数据

    ​在一个集群中,一个导入数据的进程锁住不动,所有的client都在等待一个region (因而也就是一个单个节点),过了一会后,变成了下一个region…​如果使用了单调递增 或者时序的key便会造成 ...

  10. 如何知道一个EXE使用什么开发语言开发的

    一般是看EXE调用哪些DLL,这可以使用VC++中的工具Dependency Walker,它可以列出静态链接的所有DLL. 如果EXE中的DLL包括MSVBVM60.DLL,则是使用VB 6.0开发 ...