Sliding Window POJ - 2823 单调队列模板题

题意

给出一个数列 并且给出一个数m 问每个连续的m中的最小\最大值是多少,并输出

思路

使用单调队列来写,拿最小值来举例

要求区间最小值 就是维护一个单调递增的序列

对于样例

8 3
1 3 -1 -3 5 3 6 7

我们先模拟一遍

1.队列为空 1 进队 队列:1

2.3>队尾元素 3 进队 队列: 1 3

3.-1小于队尾元素,一直从尾部出队知道找到比-1小的元素或者队列为空 队列:-1

当队列中元素大于m的时候从队头删除元素直到队列元素小于等于m

每次操作完后取队头元素就是m区间的最小值

原理

这里其实运用了一种贪心和时间的思想

当要进区间的数小于之前队列里的所有的数的时候,这个时候之前的数都没用了,因为只要包括了这个数的区间,最小值一定是小于等于这个数的,而窗口已经滑动了包括这个数了,所以之前包括这个数的区间的大于其的值都可以舍弃了

当要进区间的数不是小于之前队列里的所有的数的时候,比这个数小的数如果条件允许(也就是队列小于等于m)要保留,因为这个时候窗口最小的数是队列头的数,而进区间的数是区间第k小,只有当窗口不包括最小的这个数,队头才能出队

这其实运用了一种时间的概念(也可是说是窗口位置的变化趋势)把没有营养的元素剔除了,维护了一个单调增队列相当于维护了一个 rank ,当rank高的被封号了(窗口不包括前面的数)或者rank高的之前封号的解封了(窗口包括后面的数)rank 低的才能上来。

#include<cstdio>
#include<iostream>
using namespace std;
int n,m;
const int maxn=1e6+7;
int a[maxn],q[maxn];
void getmin(){
int head=1,tail=0; for(int i=1;i<=n;i++){
if(tail<head)q[++tail]=i;
else {
while(tail>=head&&i-q[head]+1>m)head++;
while(tail>=head&&a[q[tail]]>a[i])tail--;
q[++tail]=i;
}
if(i>=m){
printf("%d ",a[q[head]]);
}
}
}
void getmax(){
int head=1,tail=0;
for(int i=1;i<=n;i++){
if(tail<head)q[++tail]=i;
else {
while(tail>=head&&i-q[head]+1>m)head++;
while(tail>=head&&a[q[tail]]<a[i])tail--;
q[++tail]=i;
}
if(i>=m){
printf("%d ",a[q[head]]);
}
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
getmin();
cout<<endl;
getmax();
return 0;
}

Sliding Window POJ - 2823 单调队列模板题的更多相关文章

  1. poj 2823单调队列模板题

    #include<stdio.h>//每次要吧生命值长的加入,吧生命用光的舍弃 #define N  1100000 int getmin[N],getmax[N],num[N],n,k, ...

  2. caioj 1172 poj 2823 单调队列过渡题

    给定一个n个数的数列,从左至右输出每个长度为m的数列段内的最大数. 输入:第一行两个整数n和m( 1<= n <= 20 0000,m<=n).下来给出n个整数. 输出:一行一个整数 ...

  3. luoguP1886 滑动窗口(单调队列模板题)

    题目链接:https://www.luogu.org/problem/P1886#submit 题意:给定n个数,求大小为k的滑动窗口中最小值和最大值. 思路:单调队列模板题. AC代码: #incl ...

  4. 单调栈(G - Sliding Window POJ - 2823 )

    题目链接:https://cn.vjudge.net/contest/276251#problem/G 题目大意:给你n和m,然后问你对于(m,n)这中间的每一个数,(i-m+1,i)这个区间的最小值 ...

  5. POJ 2823 单调队列入门水题

    最最基础的单调队列题目.一个单增一个单减.还是可以借此好好理解一下单调队列的. #include <stdio.h> #include <string.h> #include ...

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

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

  7. AC日记——Sliding Window poj 2823

    2823 思路: 单调队列: 以前遇到都是用线段树水过: 现在为了优化dp不得不学习单调队列了: 代码: #include <cstdio> #include <cstring> ...

  8. poj 2823 单调队列

    思路:裸的单调队列. #include<iostream> #include<cstring> #include<cstdio> #include<algor ...

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

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

随机推荐

  1. UVA1401 (字典树加简单dp)

    #pragma GCC optimize(2) #include <bits/stdc++.h> #define ll long long using namespace std; ; ; ...

  2. IO流学习之字符流(一)

    IO流(Input/Output) 简介: 流是一种抽象概念,它代表了数据的无结构化传递.按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列.从流中取得数据的操作称为提取操作,而向流中添加数 ...

  3. Centos 安装SVN

    Centos 安装SVN  centos(我这里使用的是CentOS7)下yum命令即可方便的完成安装 $ sudo yum install subversion 测试安装是否成功: $ svnser ...

  4. 剑指offer 14. 链表中倒数第 k 个结点

    14. 链表中倒数第 k 个结点 题目描述 输入一个链表,输出该链表中倒数第k个结点 法一:快慢指针 快指针先走 k 步,等快指针到达尾部时,慢指针所指结点即是倒数第 k 个结点 public cla ...

  5. nginx 配置 强制访问https

    使用nginx的301状态码 server { listen ;     if ($scheme = 'http') {    return 301 https://$server_name$requ ...

  6. Django models 关联(一对多,多对多,一对一)

    参考:https://blog.csdn.net/houyanhua1/article/details/84953388

  7. Java String类型转换成Date日期类型

    插入数据库时,存入当前日期,需要格式转换 import java.text.SimpleDateFormat; formatter = new SimpleDateFormat( "yyyy ...

  8. GYCTF easyphp 【反序列化配合字符逃逸】

    基础知识可以参考我之前写的那个 0CTF 2016 piapiapia  那个题只是简单记录了一下,学习了一下php反序列化的思路 https://www.cnblogs.com/tiaopideju ...

  9. DFS/BFS-A - Red and Black

    A - Red and Black There is a rectangular room, covered with square tiles. Each tile is colored eithe ...

  10. 二分查找 python实现

    欢迎回来 [^first blood]. 要求A是升序数组 递归 只能查 数据存不存在,不能返回下标 def binary_find(A, m): if len(A) == 0: return -1 ...