[Luogu P1886]滑动窗口--单调队列入门
题目描述
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.
输入输出格式
输入格式:
输入一共有两行,第一行为n,k。
第二行为n个数(<INT_MAX).
输出格式:
输出共两行,第一行为每次窗口滑动的最小值
第二行为每次窗口滑动的最大值
这题是单调队列入门题。题意清晰明了,求区间最大(小)。第一反应是线段树或者RMQ,但是数据范围爆炸。这道题和普通的区间的区别就在于它的区间长度是固定的。所以使用时间复杂度为O(n)的单调队列来解决。
什么是单调队列呢?单调队列是一种特殊的双端队列,其内部具有单调性(有点像优先序列,但有着本质区别)。
如何实现插入?从队尾插入,若破坏了单调性,则删除队尾元素(这个删除决定了什么题能用什么题不能用),直到找到一个不影响的位置。
如何实现输出?访问队首(真是方便)
如何解决这道题?首先设一个区间为(l,r),则有max(l+1,r+1)=max(a[r+1],max(a[l+1],a[l+2]...a[r])),那么max(l+1,r+1)与max(l,r)其实是有很大一部分重叠的,那么在问题实现的时候就只需要先删除单调队列中不在区间里的数(a[l]),再插入新数(a[r+1]),剩余的不变,就可以解决了。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
inline int read(){
int res=,f=;
char ch=getchar();
while(ch<''||ch>''){
if(ch=='-')f=-;
ch=getchar();
}
while(ch>=''&&ch<=''){
res=res*+(ch-'');
ch=getchar();
}
return res*f;
}
const int N=1e6+;
int nsf[N],nbf[N],que[N],number[N],a[N];
int n,k,head,tail;
inline void INT(){
n=read();k=read();
for(int i=;i<=n;++i)a[i]=read();
}
inline void findmin(){
head=;tail=;//队头、尾初始化
for(int i=;i<=n;++i){//插入a[i]到单调序列
while(number[head]<i-k+&&head<=tail)++head;
//从队首开始找,“过时”的删除
while(a[i]<=que[tail]&&head<=tail)--tail;
//插入时从队尾插入,维护单调上升性质
number[++tail]=i;que[tail]=a[i];
//number保存插入时的“时间戳”,que表示值
nsf[i]=que[head];//当前队列中最小值
}
}
inline void findmax(){
head=;tail=;
for(int i=;i<=n;++i){
while(number[head]<i-k+&&head<=tail)++head;
while(a[i]>=que[tail]&&head<=tail)--tail;
number[++tail]=i;que[tail]=a[i];
nbf[i]=que[head];
}
}
int main(){
INT();//输入
findmin();//动态规划求单调队列最小值
findmax();
for(int i=k;i<=n;++i)printf("%d ",nsf[i]);
cout<<endl;
for(int i=k;i<=n;++i)printf("%d ",nbf[i]);
return ;
}
第一次写随笔还有点小兴奋呢~
[Luogu P1886]滑动窗口--单调队列入门的更多相关文章
- 洛谷 P1886 滑动窗口(单调队列)
题目链接 https://www.luogu.org/problemnew/show/P1886 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始 ...
- [洛谷P1886]滑动窗口 (单调队列)(线段树)
---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...
- P1886 滑动窗口 单调队列
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- Luogu P1886 滑动窗口
P1886 滑动窗口 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The a ...
- luogu P1886 滑动窗口(单调队列
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- 【洛谷P1886】滑动窗口——单调队列
没想到啊没想到,时隔两个月,我单调队列又懵了…… 调了一个小时,最后错在快读,啊!!!!(不过洛谷讨论真好啊,感谢大佬!) 考前就不推新东西了,好好写写那些学过的东西 题目点这里(我就不粘了自己点一下 ...
- cogs 495. 滑动窗口 单调队列
495. 滑动窗口 ★★ 输入文件:window.in 输出文件:window.out 简单对比时间限制:2 s 内存限制:256 MB [问题描述] 给你一个长度为N的数组,一个长为 ...
- luoguP1886 滑动窗口 [单调队列]
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- [POJ2823]Sliding Window 滑动窗口(单调队列)
题意 刚学单调队列的时候做过 现在重新做一次 一个很经典的题目 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗 ...
随机推荐
- POSIX 线程的创建与退出
前言 创建线程: pthread_create() 退出线程: pthread_exit()return pthread_cancel() 线程的创建 使用多线程,首先就需要创建一个新线程.那么线程是 ...
- 【PHP】解析PHP中的函数
目录结构: contents structure [-] 可变参数的函数 变量函数 回调函数 自定义函数库 闭包(Closure)函数的使用 在这篇文章中,笔者将会讲解如何使用PHP中的函数,PHP是 ...
- 说说erlang tuple和record结构
erlang有两种复合结构.tuple和list,两者的区别是tuple子元素的个数是固定不变的.声明后就不能改变了.而list是可变的,能够通过[H|T]来取出或插入新元素. record有点像C/ ...
- Navicat Premium 12破解方法
来源网址:https://www.jianshu.com/p/42a33b0dda9c 1.按步骤安装Navicat Premium,如果没有可以去官网下载:http://www.navicat.co ...
- james2.3 配置收件 之 MariaDB数据库配置
james我们公司一直都是使用的2.3这个稳定版本,现在已经有3.0了,不过无所谓,能用就行 基于2.3,来进行一些配置,主要是接受邮件,之前的博文如何安装的,这里不多做介绍了,链接参考:https: ...
- atitit 读书与获取知识资料的attilax的总结.docx
atitit 读书与获取知识资料的attilax的总结.docx 1.1. 读书即是获取知识,获取资料,获取信息的一种方式 2 2. 获取资料信息的目的,有什么作用,有什么用途?? 2 2.1. 扩大 ...
- Windows7系统不显示.gitignore文件名
从码云拉取项目后,发现Win7下不能显示.giignore文件名. 这是因为Win7系统默认隐藏了已知的拓展名,而.gitignore逗号前没有字符,于是显示的文件命是空白的. 打开工具—文件夹选项, ...
- 会使用基本的Render函数后,就会想,这怎么用 v-for/v-if/v-model;我写个vue Render函数进阶
https://blog.csdn.net/wngzhem/article/details/54291024
- rabbitmq web管理
celery突然连接不上rabbitmq server,结果找半天发现是rabbitmq卡的不行... rabbitmq 设置web管理,添加用户 rabbitmqctl list_queues | ...
- maven and jwt
以目前浅薄的理解,jwt就是一种加密token的手段,这个token也只有自己能解开,如果客户端以cookie存这个token,可能会存在cookie被窃取的情况. 另外,jwt这中加密方式因为有过期 ...