Sliding Window
Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 41844   Accepted: 12384
Case Time Limit: 5000MS

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
The array is [1 3 -1 -3 5 3 6 7], and k is 3.

Window position Minimum value Maximum value
[1  3  -1] -3  5  3  6  7  -1 3
 1 [3  -1  -3] 5  3  6  7  -3 3
 1  3 [-1  -3  5] 3  6  7  -3 5
 1  3  -1 [-3  5  3] 6  7  -3 5
 1  3  -1  -3 [5  3  6] 7  3 6
 1  3  -1  -3  5 [3  6  7] 3 7

Your task is to determine the maximum and minimum values in the sliding window at each position.

Input

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line. 

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values. 

Sample Input

  1. 8 3
  2. 1 3 -1 -3 5 3 6 7

Sample Output

  1. -1 -3 -3 -3 3 3
  2. 3 3 5 5 6 7

双端队列介绍:

deque和vector一样都是标准模板库中的内容,deque是双端队列,在接口上和vector非常相似,在许多操作的地方可以直接替换。假如读者已经能够有效地使用vector容器,下面提供deque的成员函数和操作,进行对比参考。

deque<type>q;

q.empty():判断队列是否为空

q.front()  ,q.back()  队列的首元素和尾元素

q.begin() ,q.end() 返回队列首元素和结尾地址

q.push_front() ,q.push_back() 分别在队首和队尾插入元素

q.pop_front() ,q.pop_back() 删除首元素和尾元素

q.size() 返回容器中元素的个数

q.clear() 清空所有元素

本题最好采用模拟队列,缩短时限,分析怎样维护递增单调队列,开一个结构体要有id序号,和v值两个内容,首先当队列为空的时候,加入第一个元素;对于下一个将要加入的元素,把该元素a的大小和队尾的元素大小tail进行比较,如果a>tail,则移除尾元素,继续比较,直到a<=tail时把a加入到队列的尾部,当k个连续的数列向后移动时,队列中的前面的元素可能已经不再此范围内了,所以还要判断首元素的序号是不是在此时的范围内,如果不在,这删除首元素(即head++)直到满足条件为止,这样便可以维护一个单调递增队列

当维护单调递减序列的道理同上

程序:

  1. #include"cstdio"
  2. #include"cstring"
  3. #include"cstdlib"
  4. #include"cmath"
  5. #include"string"
  6. #include"map"
  7. #include"cstring"
  8. #include"algorithm"
  9. #include"iostream"
  10. #include"set"
  11. #include"queue"
  12. #include"stack"
  13. #define inf 1000000000000
  14. #define M 1000009
  15. #define LL long long
  16. #define eps 1e-12
  17. #define mod 1000000007
  18. #define PI acos(-1.0)
  19. using namespace std;
  20. int a[M],maxi[M],mini[M];
  21. struct node
  22. {
  23. int v,id;
  24. node(){}
  25. node(int id,int v)
  26. {
  27. this->v=v;
  28. this->id=id;
  29. }
  30. }qmin[M*2],qmax[M*2];
  31. int main()
  32. {
  33. int n,k;
  34. while(scanf("%d%d",&n,&k)!=-1)
  35. {
  36. int minhead=0,mintail=0;
  37. int maxhead=0,maxtail=0;
  38. int cnt=0;
  39. for(int i=1;i<=n;i++)
  40. {
  41. scanf("%d",&a[i]);
  42. if(i<=k)
  43. {
  44. while(mintail>minhead&&a[i]<qmin[mintail-1].v)
  45. {
  46. mintail--;
  47. }
  48. qmin[mintail++]=node(i,a[i]);//把前k个元素入队
  49.  
  50. while(maxtail>maxhead&&a[i]>qmax[maxtail-1].v)
  51. {
  52. maxtail--;
  53. }
  54. qmax[maxtail++]=node(i,a[i]);
  55. }
  56. }
  57. mini[cnt]=qmin[minhead].v;
  58. maxi[cnt++]=qmax[maxhead].v;
  59. for(int i=k+1;i<=n;i++)
  60. {
  61. while(mintail>minhead&&a[i]<qmin[mintail-1].v)//删除比a[i]小的尾元素
  62. {
  63. mintail--;
  64. }
  65. qmin[mintail++]=node(i,a[i]);
  66. while(mintail>minhead&&i-k>=qmin[minhead].id)//删除不再范围内的首元素
  67. {
  68. minhead++;
  69. }
  70.  
  71. while(maxtail>maxhead&&a[i]>qmax[maxtail-1].v)
  72. {
  73. maxtail--;
  74. }
  75. qmax[maxtail++]=node(i,a[i]);
  76. while(maxtail>maxhead&&i-k>=qmax[maxhead].id)
  77. {
  78. maxhead++;
  79. }
  80. mini[cnt]=qmin[minhead].v;
  81. maxi[cnt++]=qmax[maxhead].v;
  82. }
  83. printf("%d",mini[0]);
  84. for(int i=1;i<cnt;i++)
  85. printf(" %d",mini[i]);
  86. printf("\n%d",maxi[0]);
  87. for(int i=1;i<cnt;i++)
  88. printf(" %d",maxi[i]);
  89. printf("\n");
  90. }
  91. return 0;
  92. }

  

双端队列(单调队列)poj2823 区间最小值(RMQ也可以)的更多相关文章

  1. Java数据结构——用双端链表实现队列

    //================================================= // File Name : LinkQueue_demo //---------------- ...

  2. POJ 2823 Sliding Window + 单调队列

    一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1)   从队首删除 (2)   从队尾删除 (3)   从队尾插入 (4)   ...

  3. 与图论的邂逅01:树的直径&基环树&单调队列

    树的直径 定义:树中最远的两个节点之间的距离被称为树的直径.  怎么求呢?有两种官方的算法(不要问官方指谁我也不晓得): 1.两次搜索.首先任选一个点,从它开始搜索,找到离它最远的节点x.然后从x开始 ...

  4. Sliding Window - 题解【单调队列】

    题面: An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving fr ...

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

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

  6. POJ3162 Walking Race(树形DP+尺取法+单调队列)

    题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...

  7. 51nod 1050 循环数组最大子段和 单调队列优化DP

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这个呢,这个题之前 求一遍最大值  然后求一遍最小值 ...

  8. Second My Problem First HDU - 3706 单调队列

    单调队列 单调队列是指一个队列内部的元素具有严格单调性的一种数据结构,分为单调递增队列和单调递减队列. 单调队列满足两个性质 1.单调队列必须满足从队头到队尾的严格单调性. 2.排在队列前面的比排在队 ...

  9. P1886 滑动窗口 /【模板】单调队列 方法记录

    原题链接 滑动窗口 /[模板]单调队列 题目描述 有一个长为 \(n\) 的序列 \(a\),以及一个大小为 \(k\) 的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最 ...

随机推荐

  1. flex mxmlc 手动编译项目

    首先: 1.下载flex的sdk,如果你电脑有装flash builder,它自带了一份,位于安装目录的sdks目录下. 备注:(sdk依赖java的jre) 2.配置mxmlc的java运行环境jr ...

  2. Android 的上下文菜单: Context Menu,registerForContextMenu(getListView())

    概述: Android 的上下文菜单类似于 PC 上的右键菜单.当为一个视图注册了上下文菜单之后,长按(2 秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单.任何视图都可以注册上下文菜单,不过, ...

  3. XMLHttpRequest函数

    function createXmlHttpRequest(){ if(window.ActiveXObject){ return new ActiveXObject("Microsoft. ...

  4. HBase的完全分布式的搭建与部署,以及多master

    一:前提准备 1.设置时间同步 2.清空logs,datas 3.格式化集群 bin/hdfs namenode -format 4.重启集群 sbin/start-dfs.sh sbin/start ...

  5. SimpleUrlHandlerMapping 使用

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  6. JavaSE的知识

    一 SE的知识体系: java基础: 一基础语法 8个基本数据类型-->8个包装类 数据类型转换: 自动转换(从小到大) 强制转换(从大到小) 注意:int 和char 分支与判断: if(){ ...

  7. angularJS自定义指令模板替换

    <html> <head> <meta charset="utf-8"/> <title></title> </h ...

  8. linux pipe

    1. 函数说明 pipe(建立管道): 1) 头文件 #include<unistd.h> 2) 定义函数: int pipe(int filedes[2]); 3) 函数说明: pipe ...

  9. [LeetCode]题解(python):092 Reverse Linked List II

    题目来源 https://leetcode.com/problems/reverse-linked-list-ii/ Reverse a linked list from position m to  ...

  10. DDS杂散频谱来源:谐波超Nyquist 折返