【模板】滑动窗口最值(单调队列)/洛谷P1886
题目链接
https://www.luogu.com.cn/problem/P1886
题目大意
有一个长为 \(n\) 的序列 \(a\) ,以及一个大小为 \(k\) 的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
题目解析
使用 \(C++\) 的 \(STL\) 库中的 \(deque\) 。
以窗口最小值为例,设该双端队列为 \(Q\) ,其队头则为每一次的答案:
首先,保证 \(Q\) 中均为未过期的值(即, \(Q\) 中元素均在窗口中)。
然后,比较 \(Q\) 的队头与新加入的值 \(a[i]\) 。
- 若 \(a[i]\) 更小,则可以清空队列,加入 \(a[i]\) (因为此时 \(a[i]\) 不但最新,而且最小)。
- 若原队头更小,将 \(a[i]\) 加入队尾,但是在加入之前,确保 \(a[i]\) 大于队尾(如果 \(a[i] \leq\) 队尾,则明显更优,队尾就废弃直接弹出了)。
这样,就可以保证答案的正确性了。
其次,我们来考虑复杂度,队列中长度总不大于窗口大小,每一个元素只进出一次, \(a[i]\) 总比较次数不超过 \(n\) 次,因此总的时间复杂度为 \(O(n)\) 。
最大值同理。
参考代码
#include <bits/stdc++.h>
using namespace std;
deque <pair <int, int> > Q;
vector <int> a;
int main()
{
int n, k, x;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; ++i) {
scanf("%d", &x);
a.push_back(x);
}
/*求滑动窗口最小值*/
for (int i = 0; i < n; ++i) {
if (!Q.empty()) {
if (a[i] <= Q.front().first) {Q.clear(); Q.emplace_front(a[i], i);}
else {
while (a[i] <= Q.back().first) Q.pop_back();
Q.emplace_back(a[i], i);
}
}
else Q.emplace_back(a[i], i);
if (i >= k-1) {
while (!Q.empty() && Q.front().second < i-k+1) Q.pop_front();
if (!Q.empty()) printf("%d ", Q.front().first);
}
}
putchar('\n');
Q.clear();
/*求滑动窗口最大值*/
for (int i = 0; i < n; ++i) {
if (!Q.empty()) {
if (a[i] >= Q.front().first) {Q.clear(); Q.emplace_front(a[i], i);}
else {
while (a[i] >= Q.back().first) Q.pop_back();
Q.emplace_back(a[i], i);
}
}
else Q.emplace_back(a[i], i);
if (i >= k-1) {
while (!Q.empty() && Q.front().second < i-k+1) Q.pop_front();
if (!Q.empty()) printf("%d ", Q.front().first);
}
}
putchar('\n');
return 0;
}
感谢支持!
【模板】滑动窗口最值(单调队列)/洛谷P1886的更多相关文章
- 题解【洛谷P1886】滑动窗口 /【模板】单调队列
题面 单调队列模板题. 单调队列可以从队首和队尾出队. 队列中的元素大小具有一定的顺序. 具体可参考这一篇题解 #include <bits/stdc++.h> #define itn i ...
- 【洛谷P1886】滑动窗口——单调队列
没想到啊没想到,时隔两个月,我单调队列又懵了…… 调了一个小时,最后错在快读,啊!!!!(不过洛谷讨论真好啊,感谢大佬!) 考前就不推新东西了,好好写写那些学过的东西 题目点这里(我就不粘了自己点一下 ...
- [洛谷P1886]滑动窗口 (单调队列)(线段树)
---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...
- 洛谷 P1886 滑动窗口(单调队列)
题目链接 https://www.luogu.org/problemnew/show/P1886 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始 ...
- 洛谷 P1886 滑动窗口(单调队列)
嗯... 题目链接:https://www.luogu.org/problem/P1886 首先这道题很典型,是标准的单调队列的模板题(也有人说单调队列只能解决这一个问题).这道题可以手写一个队列,也 ...
- 关于双端队列 deque 模板 && 滑动窗口 (自出)
嗯... deque 即为双端队列,是c++语言中STL库中提供的一个东西,其功能比队列更强大,可以从队列的头与尾进行操作... 但是它的操作与队列十分相似,详见代码1: 1 #include < ...
- 洛谷P1886 滑动窗口(POJ.2823 Sliding Window)(区间最值)
To 洛谷.1886 滑动窗口 To POJ.2823 Sliding Window 题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每 ...
- 【洛谷P1886】滑动窗口
滑动窗口 [题目描述] 有N个数字,以及一个大小为k的窗口.现在这个窗口从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 思路: k<=N<=1000000,暴 ...
- 洛谷 P1886 滑动窗口
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
随机推荐
- lib库无法加载的情况分析
最近升级vs2017的时候遇到无法加载库的问题,在网上查找问题,网上给出可能有三种情况导致该问题:路径是否正确:库依赖是否齐全:库版本是否正确.最直接的方法就是用depends软件去查询,是否有模块有 ...
- allegro查看线宽的方法
- 【BZOJ-2199】奶牛议会
链接: BZOJ-2199 题意: 给出 \(n(1\leq n\leq 1000)\) 个点,\(m(1\leq m\leq 4000)\) 个形如:"点 \(a\) 取 \(ca\) 或 ...
- 如何使用原生的Ribbon
什么是Ribbon 之前分析了如何使用原生的Feign,今天我们来研究 Netflix 团队开发的另外一个类库--Ribbon. Ribbon 和 Feign 有很多相似的地方,首先,它们本质上都是 ...
- Manacher算法 求 最长回文子串
1 概述(扯淡) 在了解Manacher算法之前,我们得先知道什么是回文串和子串. 回文串,就是正着看反着看都一样的字符串.比如说"abba"就是一个回文串,"abbc& ...
- 第06课 OpenGL 纹理映射
纹理映射: 在这一课里,我将教会你如何把纹理映射到立方体的六个面. 学习 texture map 纹理映射(贴图)有很多好处.比方说您想让一颗导弹飞过屏幕.根据前几课的知识,我们最可行的办法可能是很多 ...
- hdu 1847 Good Luck in CET-4 Everybody! (简单博弈)
题意: n张牌,双方轮流抓取.每人每次抓取的牌数必须是2的幂次(1,2,4,8...). 最后抓完的人胜. 思路 : 考虑剩3张牌,后手胜. 考虑3的倍数.假设先抓者当轮抓2x 张,2x %3等于1或 ...
- 【Python+postman接口自动化测试】(8)以青云客机聊天器人和图灵聊天机器人接口示范python发送get和post
以青云客机器人和图灵机器人接口示范python发送get和post 发送请求,我们这里主要使用Python的一个第三方包(需要先安装):requests. Python3自带的http.client和 ...
- ORACLE,mysql中替换like的函数
数据库中存储了海量的数据,当查询时使用like,速度明显变慢.我在做项目时,发现使用内部函数INSTR,代替传统的LIKE方式查询,并且速度更快. INSTR()函数返回字符串中子字符串第一次出现的位 ...
- Mysql5.7和8.0版本的文件夹版安装教程(整合版,超详细)
安装Mysql(5.7版本) 下载地址在这里可以自选版本,找到合适的版本进行下载 解压安装包 配置环境变量 win+r 输入 sysdm.cpl 点击高级 点击环境变量 新建一个系统变量 变量名为MY ...