滑动窗口
滑动窗口
https://ac.nowcoder.com/acm/problem/50528
首先,单调队列具有两个性质
1.队列中的元素其对应在原来的列表中的顺序必须是单调递增的。
2.队列中元素的大小必须是单调递*(增/减/甚至是自定义也可以)
这个题是单调队列的模板题,因为范围最大时1e6,所以这里直接用数组来模拟队列即可。
1.维护队首(就是如果你已经是当前的m个之前那你就可以被删了,head++)
2.在队尾插入(每插入一个就要从队尾开始往前去除冗杂状态)
/*Keep on going Never give up*/ #pragma GCC optimize(3,"Ofast","inline") #include <bits/stdc++.h> const int maxn = 2e5+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int mod = 100000000; using namespace std; int q1[1000010],q2[1000010]; int a[1000010]; int head,top; int n,k; void imax(){ head=1,top=0; for(int i=1;i<=n;i++){ while(head<=top&&i-q1[head]+1>k) head++; while(head<=top&&a[q1[top]]<a[i]) top--; q1[++top]=i; if(i>=k) printf("%d ",a[q1[head]]); } printf("\n"); return ; } void imin(){ head=1,top=0; for(int i=1;i<=n;i++){ while(head<=top&&i-q2[head]+1>k) head++; while(head<=top&&a[q2[top]]>a[i]) top--; q2[++top]=i; if(i>=k) printf("%d ",a[q2[head]]); } printf("\n"); return ; } int main() { cin>>n>>k; for(int i=1;i<=n;i++) scanf("%d",&a[i]); imin(); imax(); return 0; }