【洛谷】P1440 求区间最小值

来源:互联网 发布:mac如何整理文件夹 编辑:程序博客网 时间:2024/05/17 06:37

传送门


这道题目一眼看去,先想到的必然是暴力,但是数据范围mn2000000太吓人,所以放弃这个想法,那么我们一步步分析样例是如何得来的:

/*6 27 8 1 4 3 2077113*/
  1. 因为第一个数前面没有数,输出0
  2. 第二个数之前的最小数为7,输出7
  3. 第三个数之前2个的最小数为7,输出7
  4. 第四个数之前2个的最小数为1,输出1
  5. 第五个数之前2个的最小数为1,输出1

这段分析看到很头晕,但是如果我们使用一个辅助数组q来帮助我们理解,又会大不一样。


大家看,这张图生动形象地说明了这道题目就是一个裸的单调队列,具体看代码:

#include<bits/stdc++.h>using namespace std;int a[2000010],q[2000010],head=1,tail;int main(){    int i,j,k,n,m;    scanf("%d%d",&n,&m);    for(i=1;i<=n;i++)        scanf("%d",&a[i]);    for(i=1;i<=n;i++){        printf("%d\n",a[q[head]]);//这个就是输出单调队列的队首        if(i-q[head]+1>m && head<=tail)head++;//这个是判断队首是否在集合之中,如果不在,那么他的下一个必然在[这个很绕啊]        while(a[i]<a[q[tail]] && head<=tail)tail--;//维护单调队列[上升]        q[++tail]=i;[入队]    }    return 0;}

整个代码就是这么简单,根本不需要线段树之类的大神用具

原创粉丝点击