我在知乎上看到一句话,如一道晴天霹雳:

“如果一个选手比你小还比你强,你就可以退役了。”——单调队列的原理

题意

link(more:P1714

给定一个长度为 \(n\) 的整数序列,从中找出一段长度不超过 \(m\) 的子串,使得子串中所有数的和最大。

其中, \(n,m\leqslant 3\times 10^5\) 。

思路

首先要计算区间和,易想到预处理前缀和( \(s[i]=\sum\limits_{j=1}^ia[j],s[0]=0\) ),那么问题可以转化为:找出两个端点 \(l,r(r-l\leqslant m)\) ,使 \(s[r]-s[l]\) 最大。

我们可以先枚举右端点 \(r\) ( \(l\) 也就随之确定),当 \(r\) 固定时,肯定希望 \(s[l]\) 越小越好,问题又可转化为:找出左端点 \(l(l\in[i-m,i-1])\) ,使 \(s[l]\) 最小。

由此,可以易想到一个 \(O(nm)\) 的算法,但显然超时,∵我们把所有情况都进行处理,其实所有 \([i-m,i-1]\) 区间内大于最小值的数都是无用的,但又不可能对区间排序。(属于是火上浇油)

那我们就希望把区间值放到另一个结构里计算,以较高的效率从中得到最小值,且要符合 \(r\) 不断右移,从右边进新值,并从左边出旧值,还要保持单调性。

∴想到用 \(\boxed{单调队列}\) 来维护区间。

假设序列为 \(\{1,-3,5,1,-2,-3\}\) ,则 \(s=\{1,-2,3,4,2,5\}\) 。

已知队列是先进先出的顺序,我们要使进来的值单调(例如可以单调递增),那么我们抽象对比一下两个值 \(x,y\) ,且按顺序进队。如果 \(x\geqslant y\) ,那么 \(x\) 完全就没有用了,把它弹出,继续按照这个逻辑,如图:



(为便于形象展示,单调队列图中存值,实际代码中,为方便调用,存对应下标)

维护时有两种操作:

  • 队头需要弹出值,超过长度限制的值弹出。
  • 队尾需要加入值,不断将前面大于自己的数删掉。

可见,维护时每个点最多进队、出队一次,总的时间复杂度就降到了 \(O(n)\) 。

code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
int n,m;
int Q[N],h,t;
ll s[N];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
s[i]=s[i-1]+x;
}
ll ans=LLONG_MIN;
for(int i=1;i<=n;i++)
{
while(h<=t && Q[h]<i-m) h++;
ans=max(ans,s[i]-s[Q[h]]);
while(h<=t && s[Q[t]]>=s[i]) t--;
Q[++t]=i;
}
cout<<ans;
return 0;
}

总结

单调队列的思想:在决策集合(队列)中及时排除一定不是最优解的选择。

[0x12] 135.最大子序和【单调队列】的更多相关文章

  1. CH1201 最大子序和 (单调队列)

    题目链接: AcWing 牛客 题目描述 输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当 ...

  2. CH 1201 - 最大子序和 - [单调队列]

    题目链接:传送门 描述输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大. 例如 $1,-3,5,1,-2,3$. 当 $m=4$ 时,$S=5+1-2+3=7$:当 ...

  3. AcWing:135. 最大子序和(前缀和 + 单调队列)

    输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大. 输入格式 第一行输入两个整数n,m. 第二行输入n个数,代表长度为n的整数序列. 同一行数之间用空格隔开 ...

  4. hdu 6319 逆序建单调队列

    题目传送门//res tp hdu 维护递增单调队列 根据数据范围推测应为O(n)的. 我们需要维护一个区间的信息,区间内信息是"有序"的,同时需要在O(1)的时间进行相邻区间的信 ...

  5. 单调栈&单调队列学习笔记!

    ummm,,,都是单调系列就都一起学了算了思想应该都差不多呢qwq 其实感觉这俩没有什么可说的鸭QAQ就是维护一个单调的东西,区别在于单调栈是一段进一段出然后单调队列是一段进另一段出?没了 好趴辣重点 ...

  6. tyvj1305 最大子序和 【单调队列优化dp】

    描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7 当m=2或m=3时,S=5+1=6 输 ...

  7. Tyvj1305最大子序和(单调队列优化dp)

    描述 输入一个长度为n的整数序列,从中找出一段不超过M的连续子序列,使得整个序列的和最大. 例如 1,-3,5,1,-2,3 当m=4时,S=5+1-2+3=7当m=2或m=3时,S=5+1=6 输入 ...

  8. 【动态规划】【单调队列】tyvj1305 最大子序和

    http://blog.csdn.net/oiljt12138/article/details/51174560 单调队列优化dp #include<cstdio> #include< ...

  9. tyvj1305 最大子序和(单调队列

    题目地址:http://www.joyoi.cn/problem/tyvj-1305 最大子序和 题目限制 时间限制 内存限制 评测方式 题目来源 1000ms 131072KiB 标准比较器 Loc ...

随机推荐

  1. 洛谷P2880 [USACO07JAN] Balanced Lineup G(树状数组/线段树)

    维护区间最值的模板题. 1.树状数组 1 #include<bits/stdc++.h> 2 //树状数组做法 3 using namespace std; 4 const int N=5 ...

  2. 基于docker安装phpmyadmin

    今天用到了phpadmin,要从头装的话,比较麻烦,所以就选择使用docker 安装 准备 任意Linux系统且已成功安装docker环境 安装phpmyAdmin 1. 拉取镜像 docker pu ...

  3. 使用thymeleaf将查询的数据显示在前台。通过使用循环的形式

    1.需要注意的点. 在 <tr th:each="book:${bookList}">中.book是自己命令的变量.${bookList}是将查询的数据放入这里,需要后 ...

  4. 学生管理系统(C语言简单实现)

    仅供借鉴.仅供借鉴.仅供借鉴(整理了一下大一C语言每个章节的练习题.没得题目.只有程序了) 文章目录 1 .实训名称 2.实训目的及要求 3. 源码 4.实验小结 1 .实训名称 实训12:文件 2. ...

  5. 两个行内元素在一起,会出现一定的间距,即使将border、padding、margin都设置为零也无济于事,那么怎么才能去除这些间距呢?

    首先这里的div设置为了行内块元素,span本身为行内元素,并且设置了* {padding: 0; margin: 0;},那怎么清除元素之间的空白缝隙呢?? (1)给元素加浮动 <!DOCTY ...

  6. 六、模型层(ORM)

    六.模型层(ORM) Django中内嵌了ORM框架,不需要直接编写SQL语句进行数据库操作,而是通过定义模型类,操作模型类来完成对数据库中表的增删改查和创建等操作. O是object,也就类对象的意 ...

  7. 实验6:开源控制器实———RYU

    一.实验目的 1.能够独立部署RYU控制器: 2.能够理解RYU控制器实现软件定义的集线器原理: 3.能够理解RYU控制器实现软件定义的交换机原理. 二.实验环境 Ubuntu 20.04 Deskt ...

  8. MongoDB - 简单了解

    什么是 NoSQL NoSQL 是一种非关系型数据库管理系统,不需要固定的架构,可以避免 JOIN 连接,并且易于扩展. NoSQL 常用于具有庞大数据存储需求的分布式数据存储,通常是大数据和实时 W ...

  9. .Net Core 3.0 对 MongoDB 的多条件(两种)查询操作

    前言   在日常开发中,偶尔会用到 MongoDB 的数据操作,也花费了一些时间调试,因此在此处记录一下,共同进步. 废话少说,出招吧! 正文 2.1 准备工作 首先需要引入 .Net 平台链接 Mo ...

  10. OpenMP 教程(一) 深入人剖析 OpenMP reduction 子句

    OpenMP 教程(一) 深入人剖析 OpenMP reduction 子句 前言 在前面的教程OpenMP入门当中我们简要介绍了 OpenMP 的一些基础的使用方法,在本篇文章当中我们将从一些基础的 ...