单调队列:

顾名思义,就是队列中元素是单调的(单增或者单减)。

在某些问题中能够优化复杂度。

在dp问题中,有一个专题动态规划的单调队列优化,以后会更新(现在还是太菜了不会)。

在你看到类似于滑动定长度区间的类似问题时可以考虑单调队列优化。

就像这道题:P1886 滑动窗口。

一道模板题。那么我们从题目入手讲解。


首先,你看完了题。。(??)

1.暴力

朴素的入门级想法就是双重for循环枚举当前区间里的每一个元素并取min和max。

因为外层for枚举区间头,内层for枚举区间内位置,所以复杂度O(外层区间长度*内层区间长度)也就是O(nk)。这题是1e6的数据啊。。T飞了。。

2.st表

学过较为高级的数据结构的同学可能会想到线段树和st表。

其中,线段树可以O(nlogn)查询,O(nlogn)修改。st表只支持查询,但是可以O(nlogn)预处理,在这个题中,没有修改的操作,所以我们可以使用st表,相对于线段树更优。

但是计算一下,实际复杂度在两千万?。。可能过,但是我没敢试。。。qwq。一般上千万的复杂度都得看脸过了。。

所以还有更稳定的算法:

3.单调队列

复杂度O(n),为线性算法。

主角来啦!

我们定义一个双端队列q,它两端都可以任意缩短增加长度,我们尝试维护它的长度为k。

当这个窗口向右移动一格时,自然的,要进队一个元素,出队一个元素。

我们尝试保证出队的那个元素为当前区间的最大(举例子)值,那么为了维护队列的单调性,我们必须使得队头的元素要比后面的元素都大。

考虑这样一个oi俗语:有些人比你小,他还比你强,那么你就可以退役了(深有同感)!

对于当前要进队的啊a[i],如果你设一个j,保证a[j]在队中切a[j]比a[i]先入队(head<j<=tail),如果a[j]比当前a[i]小(比你强大),它还先进队(比你小),是不是就抹杀掉了a[j]当最大值的机会?

那么a[j]以及那些像a[j]一类的元素(人)都可以被弹出队列(集体退役)了。。

为什么写着写着莫名辛酸。。去世吧

这也是一个重要的基础,你一定要想懂这个道理!

于是他转化成了这样一句代码:

弹出队尾。

那么,每次只要输出队头(班里的rk1)就可以了。

代码如下:

#include<cstdio>
using namespace std;
int read()
{
char ch=getchar(),last=' ';
int ans=;
while(ch>''||ch<'')last=ch,ch=getchar();
while(ch>=''&&ch<='')ans=(ans<<)+(ans<<)+ch-'',ch=getchar();
return last=='-'?-ans:ans;
} int n,a[],k,q[]; inline int minnn()//求最小值
{
int hea=,tai=;
for(int i=;i<=n;i++)
{
while(hea<=tai&&q[hea]+k<=i)hea++;
while(hea<=tai&&a[i]<a[q[tai]])tai--;//又小又强
q[++tai]=i;
if(i>=k)printf("%d ",a[q[hea]]);//输出rk1
}
printf("\n");
} inline int maxnn()//求最大值
{
int hea=,tai=;
for(int i=;i<=n;i++)
{
while(hea<=tai&&q[hea]+k<=i)hea++;
while(hea<=tai&&a[i]>a[q[tai]])tai--;//又小又强
q[++tai]=i;
if(i>=k)printf("%d ",a[q[hea]]);//输出rk1
}
printf("\n");
} int main(){
n=read(),k=read();
for(int i=;i<=n;i++)
{
a[i]=read();
}
minnn();
maxnn();
return ;
}

一篇辛酸的讲解。

完结。

希望自己不要退役

单调队列优化&&P1886 滑动窗口题解的更多相关文章

  1. 【单调队列】P1886 滑动窗口

    GET 单调队列 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: Th ...

  2. 洛谷 P1886 滑动窗口 题解

    每日一题 day26 打卡 Analysis 单调队列模板 对于每一个区间,有以下操作: 1.维护队首(就是如果你已经是当前的m个之前那你就可以被删了,head++) 2.在队尾插入(每插入一个就要从 ...

  3. P1886 滑动窗口(单调队列)

    P1886 滑动窗口 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: ...

  4. 【NOIP2017】跳房子 题解(单调队列优化线性DP)

    前言:把鸽了1个月的博客补上 ----------------- 题目链接 题目大意:机器人的灵敏性为$d$.每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),m ...

  5. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  6. BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP

    BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...

  7. 洛谷 P3957 跳房子 —— 二分答案+单调队列优化DP

    题目:https://www.luogu.org/problemnew/show/P3957 先二分一个 g,然后判断: 由于转移的范围是一个区间,也就是滑动窗口,所以单调队列优化: 可以先令队尾为 ...

  8. P1886 滑动窗口&&P1440 求m区间内的最小值

    声明:下面这两个题就不要暴力了,学一学单调队列吧 推荐博文:https://www.cnblogs.com/tham/p/8038828.html 单调队列入门题 P1440 求m区间内的最小值 题目 ...

  9. 【单调队列优化】[CF372C] Watching Fireworks is Fun

    突然发现我可能单调队列都打不来了...我太菜了... 这道题显然有$$f[i][j]=min\{f[i-1][k]+\vert j-a[i] \vert\}$$ 则$ans=\sum_{i=1}^{m ...

随机推荐

  1. redhat 5中ifconfig不能使用问题

    ifconfig不能使用问题 输入 ifconfig 命令的绝对路径, ifconfig在是/sbin这个目录下面, 所以在终端输入下列命令就可以运行此命令:/sbin/ifconfig 我们还可以修 ...

  2. 【miscellaneous】海康相机RTSP连接代码分析

    海康相机RTSP连接代码分析 最近在做海康相机rtsp连接获取音视频的工作,现在介绍一下分析过程和源码. [源码在我上传的共享资料中: http://download.csdn.net/detail/ ...

  3. 向指定用户发送WebSocket消息并处理对方不在线的情况

    使用SimpMessagingTemplate发送消息 使用org.springframework.messaging.simp.SimpMessagingTemplate类可以在服务端的任意地方给客 ...

  4. [转帖]什么是BSS/OSS,及区别和联系

    什么是BSS/OSS,及区别和联系 https://blog.csdn.net/jionghan3855/article/details/3856873 BSS:Business support sy ...

  5. PAT A1002 A+B for Polynomials(25)

    AC代码 转载自https://www.cnblogs.com/zjutJY/p/9413766.html #include <stdio.h> #include<string.h& ...

  6. Tensorflow安装错误Cannot uninstall wrapt

    解决办法:安装之前先执行:pip install wrapt --ignore-installed

  7. package[golang]学习笔记之runtime

    *获取当前函数名称,文件名称,行号等信息.通过这个函数配合Println函数可以方便的获取错误信息的位置 var n int //n==0 当前 //n==1 调用函数 //n==2 调用函数的调用函 ...

  8. jvm自带的监控机制

    Jdk为我们提供了查看java服务运行时的监控情况 1.如下图所示,打开指定目录下的jconsole.exe应用程序文件. 2.双击后跳出如下界面,可以看到,我们可以监视本地的,也可以监视远程服务.本 ...

  9. LCN分布式事务管理(一)

    前言 好久没写东西了,9月份换了份工作,一上来就忙的要死.根本没时间学东西,好在新公司的新项目里面遇到了之前没遇到过的难题.那遇到难题就要想办法解决咯,一个请求,调用两个服务,同时操作更新两个数据库. ...

  10. go之环境安装

    1)Linux安装 https://studygolang.com/dl # 在 ~ 下创建 go 文件夹,并进入 go 文件夹 mkdir ~/go && cd ~/go 下载的 g ...