题目描述

现在有一堆数字共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]),剩余的不变,就可以解决了。

代码:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. inline int read(){
  6. int res=,f=;
  7. char ch=getchar();
  8. while(ch<''||ch>''){
  9. if(ch=='-')f=-;
  10. ch=getchar();
  11. }
  12. while(ch>=''&&ch<=''){
  13. res=res*+(ch-'');
  14. ch=getchar();
  15. }
  16. return res*f;
  17. }
  18. const int N=1e6+;
  19. int nsf[N],nbf[N],que[N],number[N],a[N];
  20. int n,k,head,tail;
  21. inline void INT(){
  22. n=read();k=read();
  23. for(int i=;i<=n;++i)a[i]=read();
  24. }
  25. inline void findmin(){
  26. head=;tail=;//队头、尾初始化
  27. for(int i=;i<=n;++i){//插入a[i]到单调序列
  28. while(number[head]<i-k+&&head<=tail)++head;
  29. //从队首开始找,“过时”的删除
  30. while(a[i]<=que[tail]&&head<=tail)--tail;
  31. //插入时从队尾插入,维护单调上升性质
  32. number[++tail]=i;que[tail]=a[i];
  33. //number保存插入时的“时间戳”,que表示值
  34. nsf[i]=que[head];//当前队列中最小值
  35. }
  36. }
  37. inline void findmax(){
  38. head=;tail=;
  39. for(int i=;i<=n;++i){
  40. while(number[head]<i-k+&&head<=tail)++head;
  41. while(a[i]>=que[tail]&&head<=tail)--tail;
  42. number[++tail]=i;que[tail]=a[i];
  43. nbf[i]=que[head];
  44. }
  45. }
  46. int main(){
  47. INT();//输入
  48. findmin();//动态规划求单调队列最小值
  49. findmax();
  50. for(int i=k;i<=n;++i)printf("%d ",nsf[i]);
  51. cout<<endl;
  52. for(int i=k;i<=n;++i)printf("%d ",nbf[i]);
  53. return ;
  54. }

第一次写随笔还有点小兴奋呢~

[Luogu P1886]滑动窗口--单调队列入门的更多相关文章

  1. 洛谷 P1886 滑动窗口(单调队列)

    题目链接 https://www.luogu.org/problemnew/show/P1886 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始 ...

  2. [洛谷P1886]滑动窗口 (单调队列)(线段树)

    ---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...

  3. P1886 滑动窗口 单调队列

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

  4. Luogu P1886 滑动窗口

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

  5. luogu P1886 滑动窗口(单调队列

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

  6. 【洛谷P1886】滑动窗口——单调队列

    没想到啊没想到,时隔两个月,我单调队列又懵了…… 调了一个小时,最后错在快读,啊!!!!(不过洛谷讨论真好啊,感谢大佬!) 考前就不推新东西了,好好写写那些学过的东西 题目点这里(我就不粘了自己点一下 ...

  7. cogs 495. 滑动窗口 单调队列

    495. 滑动窗口 ★★   输入文件:window.in   输出文件:window.out   简单对比时间限制:2 s   内存限制:256 MB [问题描述] 给你一个长度为N的数组,一个长为 ...

  8. luoguP1886 滑动窗口 [单调队列]

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

  9. [POJ2823]Sliding Window 滑动窗口(单调队列)

    题意 刚学单调队列的时候做过 现在重新做一次 一个很经典的题目 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗 ...

随机推荐

  1. 每天一个linux命令:free

    1.命令简介 free (free) 命令可以显示Linux系统中空闲的.已用的物理内存及swap内存,及被内核使用的buffer. 2.用法 free [-b | -k | -m | -g | -h ...

  2. MySQL导出TSV格式文件

    可以使用mysqldump, 也可以使用mysql -e 使用mysqldump 因为要使用到 -T / --tab 参数, 需要先查看mysql设置的secure_file_priv mysql&g ...

  3. 分析轮子(五)- Vector.java

    注:玩的是JDK1.7版本 一: 先上类图,从类图上看和 ArrayList.java 非常相像,可查看 分析轮子(一)-ArrayList.java 二:然后看源码,发现和 ArrayList.ja ...

  4. Windows下安装模块mysqlclient报错处理

    Windows环境下使用pip命令安装Python模块mysqlclientpip install mysqlclient安装过程报错  [error] Microsoft Visual C++ 14 ...

  5. Atitit 酷奇的押金危机 遇到资金链断裂作为创始人应该怎么办

    Atitit 酷奇的押金危机  遇到资金链断裂作为创始人应该怎么办 遇到对方确实经营不善,资产已经还不了用户的押金怎么办?? 1. 一些重要原则 1 1.1. 二次分配原则  公平原则 1 1.2. ...

  6. [转]论SOA架构的几种主要开发方式

    面向服务架构soa以其独特的优势越来越受到企业的重视,它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署.组合和使用.服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理 ...

  7. iOS中UITextField输入判断小数点后两位

    在输入金额的UITextField中,要给予三个规则的判断 1. 只能输入数字(可以通过设置键盘类型为Decimal Pad) 2. 小数点只能有一个 3. 小数点后最多有两位数字 (可以通过正则表达 ...

  8. dubbo的服务发现和注册如何实现

    Dubbo通常我们是如何使用的? #================================================================================== ...

  9. Java多线程:Java内存模型

    参考资料: 程晓明:Java内存模型 <Java并发编程的艺术> <深入理解Java虚拟机:JVM高级特性与最佳实践>

  10. Smart Link

    Smart Link通过两个接口相互配合工作来实现功能.这样的一对接口组成了一个Smart Link组.为了区别一个Smart Link组中的两个接口,我们将其中的一个叫做主接口,另一个叫做从接口.同 ...