单调队列:

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

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

在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. centos7 httpd配置

    centos7 httpd配置 标签(空格分隔): 未分类 隐藏server信息 修改httpd.conf 设置,添加如下两行 ServerSignature Off ServerTokens Pro ...

  2. Mysql事件调度器学习

    在cassandra数据库中,有一个叫做TTL的功能,即插入一条记录时,可以指定某一字段对应的TTL值,比如30s,那么当TTL到达30s后该条记录就会被自动删除.目前MySQL并未直接提供TTL的功 ...

  3. 23.安装php和echarts进行结合展示图表

    数据展示 http://echarts.baidu.com/index.html 是一个图像展示 可以到官方实例中选择各种图 通过下载例子 新建echartdome.php <!DOCTYPE ...

  4. Python3迭代器与生成器

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退 ...

  5. 从入门到自闭之Python--MySQL数据库的操作命令

    命令: mysqld install; 配置数据库 net start mysql;启动数据库 mysql -uroot -p; 以root权限启动数据库,-p之后输入密码 mysql -uroot ...

  6. Ruby Rails学习中:调试信息和 Rails 的三种环境,Users 资源,调试器,Gravatar 头像和侧边栏

    注册 一.调试信息和 Rails 环境 现在咱们要实现的用户资料页面是我们这个应用中第一个真正意义上的动态页面.虽然视图的代码不会动态改变, 不过每个用户资料页面显示的内容却是从数据库中读取的.添加动 ...

  7. vue技术分享之你可能不知道的7个秘密

    本文是vue源码贡献值Chris Fritz在公共场合的一场分享,觉得分享里面有不少东西值得借鉴,虽然有些内容我在工作中也是这么做的,还是把大神的ppt在这里翻译一下,希望给朋友带来一些帮助. 一.善 ...

  8. Tensorflow加载预训练模型和保存模型

    转载自:https://blog.csdn.net/huachao1001/article/details/78501928 使用tensorflow过程中,训练结束后我们需要用到模型文件.有时候,我 ...

  9. 合并两个排序链表——牛客offer

    题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 解题思路: 1.一般看到合并这类的题目就会很自然的想到创建一个新的链表,然后将两个链表根据一定 ...

  10. mybatis数组和集合的长度判断及插入

    1.在使用foreach的是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下4种情况: 如果传入的是单参数且参数类型是一个List的时候,collect ...