题意
刚学单调队列的时候做过
现在重新做一次
一个很经典的题目
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
思路
单调队列
一个递增
一个递减
代码
//author: sysky #include<cstdio> #define N 1000006 #define INF 0X3FFFFFFF using namespace std; int n,k; int mina[N],maxa[N]; int minb[N],maxb[N]; int maxl=0,maxr=1,ansmax[N]; int minl=0,minr=1,ansmin[N]; int main() { int i; scanf("%d%d",&n,&k); maxa[0]=INF; mina[0]=-INF; for(int i=1,a;i<=n;i++) { scanf("%d",&a); while(maxb[maxl]<=i-k && maxl<maxr) ++maxl; while(minb[minl]<=i-k && minl<minr) ++minl; while(maxa[maxr-1]<=a && maxl<maxr) --maxr; while(mina[minr-1]>=a && minl<minr) --minr; maxa[maxr]=mina[minr]=a; maxb[maxr++]=minb[minr++]=i; ansmax[i]=maxa[maxl]; ansmin[i]=mina[minl]; } for(int i=k;i<=n;i++) printf("%d ",ansmin[i]); puts(""); for(int i=k;i<=n;i++) printf("%d ",ansmax[i]); return 0; }
END.