用单调队列优化,求最小值时维护一个单调增队列,使得队首为最小;求最大值时维护一个单调减队列,使得队尾为最大;
可以数组模拟,也可以用STL的deque(因为队列的首尾都有操作);
C++交AC,G++交TLE;
#include <cstdio>
const int maxn=1e6+100;
int a[maxn], minn[maxn], maxx[maxn], sta[maxn*2];
int k, n;
int main(){
while(~(scanf("%d%d", &n, &k))){
for(int i=0; i<n; i++)
scanf("%d", &a[i]);
int head, tail;
head=tail=0;
for(int i=0; i<k; i++){
while(head<tail&&a[i]<a[sta[tail-1]]) tail--;
sta[tail++]=i;
while(i-sta[head]>=k) head++;
}
minn[0]=a[sta[head]];
for(int i=k; i<n; i++){
while(head<tail&&a[i]<a[sta[tail-1]]) tail--;
sta[tail++]=i;
while(i-sta[head]>=k) head++;
minn[i-k+1]=a[sta[head]];
}
head=tail=0;
for(int i=0; i<k; i++){
while(head<tail&&a[i]>a[sta[tail-1]]) tail--;
sta[tail++]=i;
while(i-sta[head]>=k) head++;
}
maxx[0]=a[sta[head]];
for(int i=k; i<n; i++){
while(head<tail&&a[i]>a[sta[tail-1]]) tail--;
sta[tail++]=i;
while(i-sta[head]>=k) head++;
maxx[i-k+1]=a[sta[head]];
}
for(int i=0; i<=n-k; i++){
printf("%d%c", minn[i], i==n-k?'\n':' ');
}
for(int i=0; i<=n-k; i++){
printf("%d%c", maxx[i], i==n-k?'\n':' ');
}
}
return 0;
}