维护一个单调队列,以最小值为例,队首是最小值的下标,将新加入的元素加入到队尾,但要pop掉那些比新加入元素还要大的元素再加入队尾(即如果比队首最小值还要小将整个队列pop掉再加入队尾),但是队首元素不一定就是这个窗口的答案,它可能在窗口的左边,所以从队首开始pop掉那些下标比i-m还要小的元素,最大值同理;
#include <cstdio>
#include <queue>
using namespace std;
const int N = 1e6+10;
int n,m,a[N];
void mi_deque(){
deque<int> q;
for(int i = 0;i < n;i++){
while(!q.empty()&&a[q.back()] > a[i]){
q.pop_back();
}
q.push_back(i);
while(!q.empty()&&q.front() <= i-m){
q.pop_front();
}
if(i >= m-1){
printf("%d ",a[q.front()]);
}
}
puts("");
}
void mx_deque(){
deque<int> q;
for(int i = 0;i < n;i++){
while(!q.empty()&&a[q.back()] < a[i]){
q.pop_back();
}
q.push_back(i);
while(!q.empty()&&q.front() <= i-m){
q.pop_front();
}
if(i >= m-1){
printf("%d ",a[q.front()]);
}
}
puts("");
}
int main(){
scanf("%d%d",&n,&m);
for(int i = 0;i < n;i++) scanf("%d",a+i);
mi_deque();
mx_deque();
return 0;
}
京公网安备 11010502036488号