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

题目描述

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

例如,对于序列 [1,3,−1,−3,5,3,6,7][1,3,-1,-3,5,3,6,7][1,3,1,3,5,3,6,7] 以及 k=3k = 3k=3,有如下过程:

窗口位置最小值最大值[1   3  -1] -3   5   3   6   7 −13 1  [3  -1  -3]  5   3   6   7 −33 1   3 [-1  -3   5]  3   6   7 −35 1   3  -1 [-3   5   3]  6   7 −35 1   3  -1  -3  [5   3   6]  7 36 1   3  -1  -3   5  [3   6   7]37\def\arraystretch{1.2} \begin{array}{|c|c|c|}\hline \textsf{窗口位置} & \textsf{最小值} & \textsf{最大值} \\ \hline \verb![1 3 -1] -3 5 3 6 7 ! & -1 & 3 \\ \hline \verb! 1 [3 -1 -3] 5 3 6 7 ! & -3 & 3 \\ \hline \verb! 1 3 [-1 -3 5] 3 6 7 ! & -3 & 5 \\ \hline \verb! 1 3 -1 [-3 5 3] 6 7 ! & -3 & 5 \\ \hline \verb! 1 3 -1 -3 [5 3 6] 7 ! & 3 & 6 \\ \hline \verb! 1 3 -1 -3 5 [3 6 7]! & 3 & 7 \\ \hline \end{array} 窗口位置[1   3  -1] -3   5   3   6   7  1  [3  -1  -3]  5   3   6   7  1   3 [-1  -3   5]  3   6   7  1   3  -1 [-3   5   3]  6   7  1   3  -1  -3  [5   3   6]  7  1   3  -1  -3   5  [3   6   7]最小值133333最大值335567

输入格式

输入一共有两行,第一行有两个正整数 n,kn,kn,k
第二行有 nnn 个整数,表示序列 aaa

输出格式

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

输入输出样例 #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%50\%50% 的数据,1≤n≤1051 \le n \le 10^51n105
对于 100%100\%100% 的数据,1≤k≤n≤1061\le k \le n \le 10^61kn106ai∈[−231,231)a_i \in [-2^{31},2^{31})ai[231,231)

解析:

无法暴力T_T

暴力枚举的方式是进行 n−kn-knk 次循环,每次查找长度为k的区间的最值。这样的算法的时间复杂度为 O(n2)O(n^2)O(n2) ,无法通过本题。

单调队列

可以建立一个队列来维护这些数据。这个队列有一些特点就是:队列中的数都是原序列 aaa 中数字 aia_iai 的下标 iii ,队列随着窗口滑动而更新,保证队列中存的下标都处于当前窗口中。并且保持队首为窗口中最大数的下标。

如何实现

那么如何实现呢?假设我们找每个区间的最小值:将原序列中每个数 aia_iai 作为一个元素依次进行如下操作:如果队列为空,直接将当前元素下标 iii 入队。当队列不为空时,在加入新元素之前,检查队尾数 fff 代表的原序列数 afa_faf 是否小于 aia_iai ,若小于,则将队尾数删除,多次判断,直到队尾数 fff 代表的原序列数 afa_faf 大于 aia_iai 或队列为空。然后将 iii 放入队尾。再检查队首数 sss ,若 sss 已在我们的区间外,则将队首删去。则每段区间的最大值就是操作完的队列的队首数 sss 表示的原序列数 asa_sas

正确性验证

那么为何这样实现是正确的呢?因为我们的操作都保证了队列中的数 xxx 表示的 axa_xax 一定是单调递减的,且 asa_sas 一定是最大的,当 asa_sas 不在序列后,队列中第二个数 ttt ,一定满足 t>st>st>s。虽然 tttsss 没有必然的数量关系,但是 a(s+1)→(t−1)<at<asa_{(s+1)→(t-1)}<a_t<a_sa(s+1)(t1)<at<as,也就是说只要 ata_tat 还在序列,ata_tat 一定就是最大值!

几个注意点

但是注意最小值并不是每次操作之后队尾 fff 表示的数 afa_faf ,因为在之前的操作中可能存在最小值在队尾,而新判断的元素 ai>afa_i>a_fai>af 导致 afa_faf 被出队,iii 入队,而 aia_iai 并不是区间最小值。所以与求最大值相似,求最小值要条件相反地建一个单调队列。

由于开始时 i<ki<ki<k ,队列的变化无法表达整个区间,等到 i≥ki \geq kik 了,才可以表示第 i−k+1i-k+1ik+1 个区间的最值。

代码实现

由于两端都有出队操作,STLSTLSTL 中的普通队列 queuequeuequeue 已经无法满足。所以用 STLSTLSTL 中另一个神奇的双端队列 dequedequedeque

deque相关

deque介绍:

首尾都可插入和删除的队列为双端队列。

deque声明:

deque<元素类型> 名称; 例: deque dq;

deque在本题中可能用到的函数:

  • 队列名.push_back(x); 把x插入队尾后
  • 队列名.push_front(x); 把x插到队首
  • 队列名.back(); 返回队尾元素
  • 队列名.front(); 返回队首元素
  • 队列名.pop_back(); 删除队尾元素
  • 队列名.pop_front(); 删除队首元素
  • 队列名.empty(); 判断双端队列是否空
  • 队列名.clear(); 清空双端队列

CoDe

代码与解析基本相符,注释略。

#include<bits/stdc++.h>
using namespace std;
int n,k;
int a[1000005];
int mn[1000005];
int mx[1000005];
deque<int>dq;
int main(){cin>>n>>k;for(int i=1;i<=n;i++){cin>>a[i];}for(int i=1;i<=n;i++){while(!dq.empty()&&i-dq.front()+1>k) dq.pop_front();while(!dq.empty()&&a[dq.back()]>a[i]) dq.pop_back();dq.push_back(i);if(i>=k){mn[i]=a[dq.front()];}}for(int i=k;i<=n;i++){cout<<mn[i]<<' ';}cout<<endl;dq.clear();for(int i=1;i<=n;i++){while(!dq.empty()&&i-dq.front()+1>k) dq.pop_front();while(!dq.empty()&&a[dq.back()]<a[i]) dq.pop_back();dq.push_back(i);if(i>=k){mx[i]=a[dq.front()];}}for(int i=k;i<=n;i++){cout<<mx[i]<<' ';}return 0;
}

当然你用自己手写的双向队列来实现操作也可以,代码就不放了。我看其他大部分人都是用手写双向队列来实现操作的,代码很好找。

单点队列一般不作为单独题目出现,而是作为动态规划的一种优化出现在一些较难的动态规划题中

求赞QAQ

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/918788.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/918788.shtml
英文地址,请注明出处:http://en.pswp.cn/news/918788.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

河南萌新联赛2025第(五)场:信息工程大学补题

文章目录[TOC](文章目录)前言A.宇宙终极能量调和与多维时空稳定性验证下的基础算术可行性研究B.中位数C.中位数1F.中位数4G.简单题H.简单题I.Re:从零开始的近世代数复习&#xff08;easy&#xff09;K.狂飙追击L.防k题前言 这次萌新联赛考到了很多数学知识 A.宇宙终极能量调和…

SuperMap GIS基础产品FAQ集锦(20250804)

一、SuperMap iServer 问题1&#xff1a;iServer的名称和logo怎么自定义&#xff1f; 11.3.0 【解决办法】参考&#xff1a;https://blog.csdn.net/supermapsupport/article/details/144744640 问题2&#xff1a;iServer 刷新工作空间&#xff0c;当数据库是 PostGIS 时&#x…

AWS CloudFormation批量删除指南:清理Clickstream Analytics堆栈

概述 在AWS环境管理中,经常会遇到需要批量删除CloudFormation堆栈的情况。本文记录了一次完整的Clickstream Analytics堆栈清理过程,包括遇到的问题和解决方案,希望能为其他开发者提供参考。 背景 我们的AWS账户中部署了多个Clickstream Analytics解决方案的CloudFormati…

redis中分布式锁的应用

我们之前讲了秒杀模块的实现&#xff0c;使用了sychronized互斥锁&#xff0c;但是在集群模式下因为不同服务器有不同jvm&#xff0c;所以synchronized互斥锁失效了。 redis实现秒杀超卖问题的解决方案&#xff1a;(仅限于单体项目)-CSDN博客 这时就要找到一个多台服务器都能…

【科研绘图系列】R语言绘制微生物丰度和基因表达值的相关性网络图

文章目录 介绍 加载R包 数据下载 导入数据 数据预处理 画图 系统信息 参考 介绍 【科研绘图系列】R语言绘制微生物丰度和基因表达值的相关性网络图 加载R包 library(tidyverse) library(ggsignif) library(RColorBrewer) library(dplyr) library(reshape2) library(grid

Pycharm现有conda环境有对应env,但是添加后没反应

一、系统环境 二、异常现象 Pycharm现有conda环境有对应env&#xff1a; anaconda3的envs下也确实存在这个环境&#xff1a; 但是添加后没反应&#xff08;点击确认后&#xff0c;yolov7环境没有出现在列表中&#xff09;&#xff1a; 但是我之前在别的机子添加是没问题的。 …

Git常用指令大全:从入门到精通

Git 的常用指令&#xff0c;分为基础操作、分支管理、远程协作、撤销操作和高级功能五个部分&#xff0c;并附上实用示例&#xff1a;一、基础操作&#xff08;必会&#xff09;初始化仓库 git init # 在当前目录创建新仓库克隆远程仓库 git clone https://github.com/user/rep…

Redis (REmote DIctionary Server) 高性能数据库

Redis {REmote DIctionary Server} 高性能数据库1. What is Redis?1.1. 基于内存的数据存储2. Install Redis on Linux3. Starting and stopping Redis in the background3.1. systemctl3.2. service 4. Connect to Redis5. 退出 Redis 的命令行界面 (redis-cli)6. redis-serv…

MySQL中的DML(二)

DML(Data Manipulation Language) : 数据库操作语言&#xff0c;对数据库中表的数据进行增删改操作。 创建student表&#xff1a; CREATE DATABASE test; use test; CREATE TABLE student (id int,name varchar(255),address varchar(255),city varchar(255) );INSERT INTO stu…

linux 主机驱动(SPI)与外设驱动分离的设计思想

一、 主机驱动与外设驱动分离Linux中的SPI、I2c、USB等子系统都利用了典型的把主机驱动和外设驱动分离的想法&#xff0c;让主机端负责产生总线上的传输波形&#xff0c;而外设端只是通过标准的API来让主机端以适当的波形访问自身。因此这里涉及了4个软件模块&#xff1…

如何生成.patch?

文章目录 ​​方法 1:使用 `git format-patch`(推荐)​ ​​步骤​​ ​方法 2:使用 `diff`命令(适用于非 Git 项目)​ ​​方法 3:使用 `git diff`(生成未提交的变更)​ ​方法 4:使用 `quilt`(适用于大量补丁管理) ​如何提交补丁给上游项目?​ ​总结​​ 在 L…

【计算机网络 | 第6篇】计算机体系结构与参考模型

文章目录计算机体系结构与参考模型分层思想&#x1f342;常见的3种模型&#xff08;网络体系结构&#xff09;&#x1f426;‍&#x1f525;TCP/IP体系结构各层包含的主要协议&#x1f95d;每层所解决的主要问题&#x1f914;层次间的交互规则&#x1f95d;实体与对等实体协议服…

Autoware Universe 感知模块详解 | 第一节 感性认识多源传感器标定

传感器与感知模块 在基于规则的自动驾驶系统中&#xff0c;感知模块&#xff0c;承担着理解车体周围环境信息的重要职责。它通过融合多种传感器数据&#xff0c;与定位模块共同为规划与控制模块提供准确、系统化的输入信息。正如人可以通过眼睛观察周围的环境&#xff08;盲人也…

docker搭建java运行环境(java或者springboot)

目录1. 创建测试代码2. 编译打包3. 代码环境运行使用普通运行方式使用docker挂载项目&#xff08;长期运行&#xff09;1. 创建 Dockerfile2. 构建并后台运行使用docker swram实现零停机更新&#xff08;推荐&#xff09;1. 初始化swarm2. 创建 Dockerfile3. 使用Dockerfile 构…

哈希表特性与unordered_map/unordered_set实现分析

目录 一、哈希表核心特性总结 1.开放地址法 2.链地址法 二、unordered_map/unordered_set实现要点分析 1. 哈希表核心实现(HashTable2.h) (1) 哈希函数处理 (2) 链地址法实现 (3) 迭代器设计 (4) hashtable设计 2. unordered_map实现要点 3. unordered_map实现要点 一…

生产环境sudo配置详细指南

目录 1. 语法格式 2. 配置示例 3. 使用 /etc/sudoers.d/ 目录管理&#xff08;推荐&#xff09; 4. 基础配置&#xff1a;用户权限管理 4.1 ​​添加用户到sudo组 ​​4.2 验证用户组信息 5. sudo日志配置 5.1 修改sudoers配置文件 5.2 创建日志目录与权限设置 6. Su…

CSS动态视口单位:彻底解决移动端适配顽疾,告别布局跳动

你是否曾被这些问题困扰&#xff1a; 移动端页面滚动时&#xff0c;地址栏收缩导致页面高度突变&#xff0c;元素错位&#xff1f;100vh在移动设备上实际高度超出可视区域&#xff1f;全屏弹窗底部总被浏览器UI遮挡&#xff1f; 这些痛点背后都是传统视口单位的局限——无法响应…

【P27 4-8】OpenCV Python——Mat类、深拷贝(clone、copyTo、copy)、浅拷贝,原理讲解与示例代码

P27 4-8 1 Mat结构体2 深拷贝VS浅拷贝3 代码示例1 Mat结构体 2 深拷贝VS浅拷贝 只拷贝了头部&#xff0c;header&#xff0c;&#xff0c;但是data部分是共用的&#xff0c;速度非常快&#xff1b; 缺点&#xff0c;任意一个修改&#xff0c;另一个data跟着变&#xff0c;这就是…

容器运行时支持GPU,并使用1panel安装ollama

前言 安装Docker请看之前博文&#xff1a;Docker实战中1panel方式安装Docker。 安装 NVIDIA 容器工具包 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html 安装 先决条件 阅读有关平台支持的部分。为您的 Linux 发行版安装…

高并发内存池 性能瓶颈分析与基数树优化(9)

文章目录前言一、性能瓶颈分析操作步骤及其环境配置分析性能瓶颈二、基数树优化单层基数树二层基数树三层基数树三、使用基数树来优化代码总结前言 到了最后一篇喽&#xff0c;嘻嘻&#xff01;   终于是要告一段落了&#xff0c;接下来我们将学什么呢&#xff0c;再说吧&…