原题链接

滑动窗口 /【模板】单调队列

题目描述

有一个长为 \(n\) 的序列 \(a\),以及一个大小为 \(k\) 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

例如:

The array is \([1,3,-1,-3,5,3,6,7]\), and \(k = 3\)。

输入格式

输入一共有两行,第一行有两个正整数 \(n,k\)。

第二行 \(n\) 个整数,表示序列 \(a\)

输出格式

输出共两行,第一行为每次窗口滑动的最小值

第二行为每次窗口滑动的最大值

样例 #1

样例输入 #1

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

样例输出 #1

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

提示

【数据范围】

对于 \(50\%\) 的数据,\(1 \le n \le 10^5\);

对于 \(100\%\) 的数据,\(1\le k \le n \le 10^6\),\(a_i \in [-2^{31},2^{31})\)。

算法:单调队列

单调队列的性质

性质1:单调性

队列中的元素必须满足单调性。如果要求区间最大值,则队列单调递减;否则队列单调递增。即:队首就是要求的元素。

性质2:有序性

事实上,元素在原序列中的相对位置和在队列中的相对位置不变

我们可能进行的操作(“队列”指我们用到的单调序列,“原序列”指输入的序列)

一.当队列中无元素时,直接将原序列中的元素从队尾入队;

二.当队列中有元素时,面对即将进入的元素,若队列中的元素小于即将进入的元素,则队列中的元素不可能成为窗口中的最小值,队列中的元素从队尾出队,新元素从队尾入队。这样以来,队列中的元素就保证是单调递增的;

三.当有新元素进入时,由于不知道之后进入的元素是否比它小,那么这个元素依然有可能成为窗口中的最小值;

四.模拟窗口滑动:如果当前遍历位置与队首位置的区间大于窗口,则重复执行队首右移;

五.生成答案:当遍历的位置第一次超过窗口大小时,每遍历一个元素就会生成一个答案。由于维护的队列单调递增,则每次队首元素就是答案。

程序上的操作参见代码注释。

点击查看代码
#include<iostream>
#include<cstdio>
using namespace std;
const int N=1000005;
int n,k,h,t;
int a[N],q1[N],q2[N];
int main()
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
//t--队尾出,h++队首出,t++队尾进
//q1[],q2[]储存的都是位置,只有a[]储存的是值
for(int i=1;i<=n;i++)
{
while(h<=t&&i-q1[h]>=k) h++;
while(h<=t&&a[i]<a[q1[t]]) t--;
q1[++t]=i;
if(i>=k) printf("%d ",a[q1[h]]);
}
puts("");
for(int i=1;i<=n;i++)
{
while(h<=t&&i-q2[h]>=k) h++;
while(h<=t&&a[i]>a[q2[t]]) t--;
q2[++t]=i;
if(i>=k) printf("%d ",a[q2[h]]);
}
return 0;
}

参考:

https://blog.csdn.net/qaqwqaqwq/article/details/120429563

https://www.luogu.com.cn/blog/hankeke/solution-p1886

P1886 滑动窗口 /【模板】单调队列 方法记录的更多相关文章

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

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

  2. P1886 滑动窗口(单调队列)

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

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

    嗯... 题目链接:https://www.luogu.org/problem/P1886 首先这道题很典型,是标准的单调队列的模板题(也有人说单调队列只能解决这一个问题).这道题可以手写一个队列,也 ...

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

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

  5. 【P1886】滑动窗口(单调队列→线段树→LCT)

    这个题很友好,我们可以分别进行简单难度,中等难度,恶心难度来做.然而智商没问题的话肯定是用单调队列来做... 板子题,直接裸的单调队列就能过. #include<iostream> #in ...

  6. poj2823滑动窗口(单调队列)

    题目传送门 题意:给你一个长度为n的数列,然后用一个长度为k的窗口去框(k<n)每次保存k这个窗口中的最大值和最小值,输出. 思路:这道题最朴素的on2的做法铁定超时,然后我想过一个nlogn的 ...

  7. POJ2823 滑动窗口 (单调队列)

    来学习一下单调队列: 他只可以从队尾入队,但可以从队尾或队首出队,来维护队列的单调性.单调队列有两种单调性:元素的值单调和元素的下标单调. 单调队列可以用来优化DP.状态转移方程形如dp[i]=min ...

  8. [luoguP1866]滑动窗口(单调队列)

    传送门 可以搞2个单调队列. 然后,然后就没有然后了. # include <iostream> # include <cstdio> # include <cstrin ...

  9. 单调队列优化&&P1886 滑动窗口题解

    单调队列: 顾名思义,就是队列中元素是单调的(单增或者单减). 在某些问题中能够优化复杂度. 在dp问题中,有一个专题动态规划的单调队列优化,以后会更新(现在还是太菜了不会). 在你看到类似于滑动定长 ...

随机推荐

  1. Docker容器保姆:在centos7.6上利用docker-compose统一管理容器和服务

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_108 众所周知,一个大型的Docker容器组成的微服务应用中,容器的数量是非常巨大的,如果依赖传统的人工配置方式进行维护,对于开发 ...

  2. HDFS基础入门

    HDFS简介 HDFS(全称:Hadoop Distribute File System)分布式文件系统,是Hadoop核心组成. HDFS中的重要概念 分块存储 HDFS中的文件在物理上是分块存储的 ...

  3. Apache Pulsar Summit Asia 2020 正式启动,演讲议题征集中!

    Apache Pulsar Summit 是 Apache Pulsar 社区年度盛会,它将分布在世界各地的 Apache Pulsar 项目 Contributor.Commiter 和各企业 CT ...

  4. 前端 | HTML5基础知识

    1 HTML定义 HTML(英文Hyper Text Markup Language的缩写)中文译为"超文本标签语言",主要是通过HTML标签对网页中的文本.图片.声音等内容进行描 ...

  5. 论文解读(PairNorm)《PairNorm: Tackling Oversmoothing in GNNs》

    论文信息 论文标题:PairNorm: Tackling Oversmoothing in GNNs论文作者:Lingxiao Zhao, Leman Akoglu论文来源:2020,ICLR论文地址 ...

  6. 【manim】3b1b的"Almost" Fourier Transform复刻

    最近在做Fourier Transform的内容,记录一下今天下午的成果. 本文代码全部自行编写,需要math and music项目完整工程可以在gayhub上获取.(现在还没弄完,就先不发了.) ...

  7. No value specified for parameter 5异常

    No value specified for parameter 5 翻译:没有为参数5指定值 在sql语句中,有5个" ? "号,但是赋值的时候只赋了前面4个" ?&q ...

  8. Hack The Box( Starting Point )

    Hack The Box [Starting Point] 初始点 -- 了解渗透测试的基础知识. 这一章节对于一个渗透小白来说,可以快速的成长.以下将提供详细的解题思路,与实操步骤. TIER 0 ...

  9. CodeForces - 1701C

    Problem - C - Codeforces 题意: 每个位置对应一种适合的工人,适合的工人工作消耗1h,不适合2h,每个工人不能同时工作多个机器,问将所有机器工作完毕的最小时间是多少. 题解: ...

  10. Linux下自动删除过期备份和自动异地备份

    每天自动删除过期备份 首先编写一个简单的Shell脚本DeleteExpireBackup.sh: #!/bin/bash # 修改需要删除的路径 location="/database/b ...