【题解】P1440 求m区间内的最小值
求m区间内的最小值
题目描述:
一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。
分析:
读题之后可以发现,这道题就是在求:
给出一个长度为n的序列A,求A中所有长度为m的连续子序列中的最小值
而针对这种问题,单调队列似乎是我们最好的选择。
单调队列,说是队列,却不符合队列“先进先出”的原则,它只是沿用了队列的思想,并具有一定的单调性,拥有一个队列头head和一个队列尾tail,用head和tail来控制队列的长度,筛选队列中的元素以及保持队列的单调性。
但怎样控制队列的长度,筛选队列中的元素以及保持队列的单调性呢?
这就是单调队列的实现了。
用样例来分析一下:
6 2
7 8 1 4 3 2
这样,我们就拥有了一个初始队列:7 8 1 4 3 2
拥有上帝视角的我们可以看出答案是:
0
7
7
1
1
3
这时候,我们发现,不论第一个元素是多少,它之前m个元素的最小值永远为0(因为它之前并没有元素),而最后一个元素是多少也没有关系(因为它之后并没有元素)。
所以我们只用找到第2个到第n个元素中每个前m个元素的最小值就可以了,那么单调队列的单调性也应该是递增的,我们就可以把队列里每个元素的序号放入单调队列操作,就可以得到答案了。
于是我们可以开始模拟了:
考虑第一个元素,i=1,head=1,tail=0,q[tail]=0,a[1]=7,a[1]>a[ q[tail] ],把a[1]放入不会破坏单调性,q[head]=0,这个元素距队首元素的距离为0,则队列为:1
考虑第二个元素,i=2,head=1,tail=1,q[tail]=1,a[2]=8,a[2]>a[ q[tail] ],把a[2]放入不会破坏单调性,q[head]=1,这个元素距队首元素的距离为1,则队列为:1 2
考虑第三个元素,i=3,head=1,tail=2,q[tail]=2,a[3]=1,但a[3]<a[ q[tail] ],把a[3]放入会破坏单调性,而a[3]<a[ q[tail] ],由于求最小值,所以只能将a[ q[tail=2] ]弹出队列来保证单调性了,而a[3]>a[ q[tail=1] ],这时再将a[3]放入就不会破坏单调性了,q[head]=1,这个元素距队首元素的距离为2,达到长度m=2了,这队列头head就向后移,则队列为:3。
以此类推,直到第n-1个,因为第n个后面没有元素,所以第n个不会进入队列,每次都输出队列头对应的元素值,就得到了答案。
代码实现:
#include <iostream>
#include <cstdio>
#include <cmath>
#define maxn 2000005
using namespace std;
int n,m;
int a[maxn];
int q[maxn];
int head,tail;
int main()
{
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
head=1;
tail=0;
printf("0\n");//第一个元素它之前并没有元素
for(int i=1;i<n;i++)//从1~n-1个,第n个不进队列
{
while((head<=tail)&&((i-q[head])>=m)) head++;//控制队列的长度
while((head<=tail)&&(a[q[tail]]>=a[i])) tail--;//筛选队列中的元素
tail++;
q[tail]=i;//保持队列的单调性
printf("%d\n",a[q[head]]);//输出答案
}
return 0;
}
【题解】P1440 求m区间内的最小值的更多相关文章
- P1886 滑动窗口&&P1440 求m区间内的最小值
声明:下面这两个题就不要暴力了,学一学单调队列吧 推荐博文:https://www.cnblogs.com/tham/p/8038828.html 单调队列入门题 P1440 求m区间内的最小值 题目 ...
- 洛谷 P1440 求m区间内的最小值
传送门 思路 由于数据范围很大,所以使用单调队列,和滑动窗口这道题类似 首先第一个数输出\(0\),因为第一个数之前没有数 然后通过样例我们发现,最后一个数并没有派上什么用场,所以循环\(n-1\)轮 ...
- 洛谷—— P1440 求m区间内的最小值
https://www.luogu.org/problemnew/show/P1440 题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的 ...
- P1440 求m区间内的最小值--洛谷luogu
题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...
- luogu P1440 求m区间内的最小值
题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...
- P1440 求m区间内的最小值
题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...
- [洛谷P1440]求m区间内的最小值
题目大意:给你n个数,求出每个数前m位的最小值 题解:单调队列,用一个可以双向弹出的队列来存一串数,满足里面的数具有单调性,我们可以假设它是单调递增的,即求最小的数.那么可以把要插入的这个数与队尾元素 ...
- 洛谷 P1440 求m区间内的最小值(单调队列)
题目链接 https://www.luogu.org/problemnew/show/P1440 显然是一道单调队列题目…… 解题思路 对于单调队列不明白的请看这一篇博客:https://www.cn ...
- 求m区间内的最小值
洛谷P1440 求m区间内的最小值 ............................................................................... 以上 ...
随机推荐
- Android中对应用程序的行为拦截实现方式概要
这次是真的好长时间都没有写博客了,主要不是因为工作上的事,主要还是这个问题真的有点复杂,实现起来有点麻烦,所以研究了很长时间(大约有一个月的时间).但是幸好最后问题搞定了~~ 一.问题场景 想实现36 ...
- bzoj1047题解
[解题思路] (p.s.:刚看的时候一脸懵逼..没看见N已经给定了,还以为要用某些高明的方法..果然还是太naive了..) 两遍预处理,第一遍处理出f[i][j][0/1]表示第i行从j-n+1~j ...
- mysql之分组
1.创建分组 group by SELECT vend_id, COUNT(*) AS num_prods FROM productsGROUP BY vend_id; 在where字句之后,在ord ...
- eclipse的快捷键(常用)
ctrl+shift+r 全局查找java类 ctrl +h 全局查找包含某某内容的文件位置 ctrl +alt+h 右击方法名 选择open call hierarchy
- 1、获取APP 冷/热启动时间
最近在研究Android APP性能测试.所以发现一些有趣的东西,在这里进行分享.我们先讲第一个内容,如何获取APP冷/热启动时间?为什么要做这个测试,道理其实很简单,如果启动APP特别耗时的话,用户 ...
- 拾遗:~/.zshrc 配置
Tips: zsh 默认仅显示最近 16 条历史记录 $ # 等价于 history - :显示最近 条记录 $ history $ # 等价于 history - : 显示从第 条到最后 条,即是全 ...
- 剑指offer——43数据流中的中位数
题目描述 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值.如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值.我们 ...
- 移动端自动化测试appium 从入门到项目实战Python版✍✍✍
移动端自动化测试appium 从入门到项目实战Python版 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程 ...
- 基于Python玩转人工智能最火框架 TensorFlow应用实践✍✍✍
基于Python玩转人工智能最火框架 TensorFlow应用实践 随着 TensorFlow 在研究及产品中的应用日益广泛,很多开发者及研究者都希望能深入学习这一深度学习框架.而在昨天机器之心发起 ...
- Linux特殊位SUID、SGID、SBIT
Linux特殊位SUID.SGID.SBIT 前言 Linux中的文件权限一般有x.w.r,在某个情况下有需要用到s.t,即特殊位. 进程运行时能够访问哪些资源或文件,不取决于进程文件的属主属组,而是 ...