单调队列(滑动窗口)模板
单调队列(滑动窗口)模板
时间复杂度:\(O(n)\)
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,k,a[N],ans1[N],ans2[N];
int q[N],hd,tl;//q[N]存的是位置
void calc(int ans[]){
hd=1,tl=0;//清空
for(int i=1;i<=n;i++){//枚举窗口右端
while(hd<=tl&&i-q[hd]+1>k) q[hd++]=0;//弹出队首已经离开窗口的元素
while(hd<=tl&&a[q[tl]]>a[i]) q[tl--]=0;//从队尾踢掉之前所有比当前元素大的数
q[++tl]=i;//将当前元素位置加入队尾
if(i>=k) ans[i-k+1]=q[hd];//队头即为最小值
}
return ;
}
int main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
}
calc(ans1);//计算滑动窗口最小值位置,答案计入ans1
for(int i=1;i<=n-k+1;i++){
cout<<a[ans1[i]]<<' ';
}
cout<<'\n';
for(int i=1;i<=n;i++){
a[i]=-a[i];//取相反数
}
calc(ans2);//计算滑动窗口最大值位置(此时依旧求的是最小值位置),答案计入ans2
for(int i=1;i<=n-k+1;i++){
cout<<-a[ans2[i]]<<' ';//因为求最大值,所以再取相反数
}
return 0;
}

浙公网安备 33010602011771号