单调队列模板题
每次先把已经超过范围的扔掉。
然后把范围内不可能成为最优解的扔掉。
然后入队。
很久以前写的代码:
#include<iostream> #include<cstdio> using namespace std; #define maxn 10000007 int x,q[maxn],a[maxn],n,m,f,r; inline void Init() { scanf("%d%d",&n,&m); for(register int i=1;i<=n;i++) scanf("%d",&a[i]); } inline void Work() { if(m==1) { for(register int i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); for(register int i=1;i<=n;i++) printf("%d ",a[i]); printf("\n"); return; } q[f=++r]=1; for(register int i=2;i<m;i++) { x=a[i]; while(a[q[r]]>=x&&r>=f) r--; q[++r]=i; } for(register int i=1;i+m-1<=n;i++) { while(q[f]<i) f++; x=a[i+m-1]; while(a[q[r]]>=x&&r>=f) r--; q[++r]=i+m-1; printf("%d ",a[q[f]]); } printf("\n"); q[f=r=1]=1; for(register int i=2;i<m;i++) { x=a[i]; while(a[q[r]]<=x&&r>=f) r--; q[++r]=i; } for(register int i=1;i+m-1<=n;i++) { while(q[f]<i) f++; x=a[i+m-1]; while(a[q[r]]<=x&&r>=f) r--; q[++r]=i+m-1; printf("%d ",a[q[f]]); } printf("\n"); } int main() { Init(); Work(); return 0; }