就是求区间和与区间最小值的积的最大值 但是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. SQLServer低版本附加高版本的数据库常用处理方法

    SqlServer低版本数据库不能直接还原或附加Sql高版本数据库或备份文件,我们常用DTS互导的方式,如果不同版本数据库不可访问,可以使用高版本数据库的DTS导出整个库的相应低版本建库脚本与数据,然 ...

  2. [翻译]在Windows版或MacOS版的Microsoft Edge上安装一个谷歌浏览器拓展

    原文:Install a Chrome Web Store extension on Microsoft Edge for Windows and MacOS 拓展阅读:What to expect ...

  3. [转]使用nodejs-koa2-mysql-sequelize-jwt 实现项目api接口

    本文转自:https://blog.csdn.net/yibowanbo/article/details/80521849 nodejs-koa2-mysql-sequelize-jwt技术栈:nod ...

  4. GTX 750TI 使用 ffmpeg 时无法用 GPU HEVC(h.265) 进行加速

    官网版本好像不是能加速的,所以在github上找到一个已经带gpu加速的. https://github.com/illuspas/ffmpeg-hw-win32 GPU加速命令格式: ffmpeg. ...

  5. 了解spring

    一.spring简介 Spring是一个JavaEE轻量级的一站式的开发框架(spring的可插拔特性,企业用于整合其他框架)轻量级:使用最少的代码启动程序,根据所需选择功能选择模块使用一站式:提供了 ...

  6. 【Tomcat】Tomcat工作原理及简单模拟实现

    Tomcat应该都不陌生,我们经常会把写好的代码打包放在Tomcat里并启动,然后在浏览器里就能愉快的调用我们写的代码来实现相应的功能了,那么Tomcat是如何工作的? 一.Tomcat工作原理 我们 ...

  7. dubbo-源码分析Provider

    Dubbo provider启动原理: 当我们的dubbo启动我们的spring容器时spring 初始化容器的时候会查找META-INF/spring.handles文件查找对应的Namespace ...

  8. select设置text的值选中(兼容ios和Android)基于jquery

    前一段时间改了一个bug,是因为select引起的.当时我没有仔细看,只是把bug改完了就完事了,今天来总结一下. 首先说option中我们通常会设置value的属性的,还有就是text值的,请参见下 ...

  9. Util6 MIS2.0 (优六信息化管理系统框架)

    Util6 MIS一套基于ASP.NET MVC5 + Layui 开发的通用信息化管理系统快速开发框架 系统操作界面简洁, 项目结构清晰,功能模块化设计,支撑框架轻量高效,代码层级分离,注释完整,可 ...

  10. (最完美)MIUI12系统的Usb调试模式在哪里开启的步骤

    当我们使用安卓手机通过数据线链接到Pc的时候,或者使用的有些app比如我们公司营销小组当使用的app引号精灵,之前的老版本就需要开启usb调试模式下使用,现当新版本不需要了,如果手机没有开启usb调试 ...