就是求区间和与区间最小值的积的最大值 但是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. 原生js 遍历文件夹分析xml并保存

    其实这种功能,网上相关的代码多的是,我也是因为今天正好要用到这个功能,所以临时写了下,放这里保存下,以便将来自己或者别人用的上吧. 当然我写的是一个hta文件.下面是完整js代码,都是调用active ...

  2. Reactor 典型的 NIO 编程模型

    Doug Lea 在 Scalable IO in Java 的 PPT 中描述了 Reactor 编程模型的思想,大部分 NIO 框架和一些中间件的 NIO 编程都与它一样或是它的变体.本文结合 P ...

  3. 图像检索(5):基于OpenCV实现小型的图像数据库检索

    本文对前面的几篇文章进行个总结,实现一个小型的图像检索应用. 一个小型的图像检索应用可以分为两部分: train,构建图像集的特征数据库. retrieval,检索,给定图像,从图像库中返回最类似的图 ...

  4. 面试被问烂的 Spring IOC(求求你别再问了)

    广义的 IOC IoC(Inversion of Control) 控制反转,即"不用打电话过来,我们会打给你". 两种实现: 依赖查找(DL)和依赖注入(DI). IOC 和 D ...

  5. 迭代器模式 Iterator 行为型 设计模式(二十)

    迭代器模式(Iterator)   走遍天下,世界那么大,我想去看看   在计算机中,Iterator意为迭代器,迭代有重复的含义,在程序中,更有“遍历”的含义 如果给定一个数组,我们可以通过for循 ...

  6. Django学习之八:forms组件【对form舒心了】

    目录 Django forms组件 bound and unbound form instance forms渲染有关 隐藏一个字段,不渲染它 form 校验 form类 ModelForm 利用Mo ...

  7. Django之模板系统

    变量的使用: def test(request): num=1 s='hello' li=[1,2,['a','b']] dic={'name':'w','age':1} se={1,2,3} tup ...

  8. cesium 之地图显示坐标、比例尺、海拔高度效果篇(附源码下载)

    前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...

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

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

  10. bcrypt 安装不成功解决办法

    同一个项目,公司和家里的 node.js 的版本不同,导致项目安装依赖包时 bcrypt 安装不成功. 家里的版本为:8.11.3 公司的版本为:10.14.2 在当前项目中执行完下面两个命令后,报错 ...