队尾:比较队尾元素与
a
i
a_i
ai的大小关系,若队尾元素小于
a
i
a_i
ai,则弹出,保证队列保持单调
最小值的维护同理
对于本题窗口滑动的操作,只需模拟窗口一位一位移动的过程,每次将下一个数加入队列即可
代码:
#include<bits/stdc++.h>usingnamespace std;constint N =1e6+10;int a[N], w[N], v[N], n, k;// w储存队列中元素,v储存队列下标对应的数组下标voidmaxx(){int st =1, ed =0;for(int i =1; i <= n; i++){while(st <= ed && w[ed]< a[i])--ed;//从尾端弹出队列以添加元素
w[++ed]= a[i];
v[ed]= i;while(v[st]<(i - k +1)) st++;//从前端弹出队列中元素都在窗口内if(i >(k -1))printf("%d ", w[st]);//已经将窗口内元素都统计完了,于是输出}}voidminn(){int st =1, ed =0;for(int i =1; i <= n; i++){while(st <= ed && w[ed]> a[i])--ed;
w[++ed]= a[i];
v[ed]= i;while(v[st]< i - k +1)++st;if(i >(k -1))printf("%d ", w[st]);}}intmain(){scanf("%d%d",&n,&k);for(int i =1; i <= n; i++){scanf("%d",&a[i]);}minn();puts(" ");memset(w,0,sizeof(w));maxx();return0;}