用单调队列优化,求最小值时维护一个单调增队列,使得队首为最小;求最大值时维护一个单调减队列,使得队尾为最大;
可以数组模拟,也可以用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; }