单调队列学习笔记(还是再回首)
单调队列的应用很常见,比如用于dp优化,以及滑动窗口问题等。
其思想也比较简单易懂。我们以求区间最大值的单调队列为例。
具体的来讲,我们让队头始终是最大的元素。为了保证数都在区间内,我们记录一个
代码(这里最大值和最小值都求出来了):
#include<bits/stdc++.h> using namespace std; const int N = 1e6+100; int lmx = 1, rmx, lmn = 1, rmn; int tmx[N], tmn[N]; int qmx[N], qmn[N]; int a[N]; int n, K; void push_mx(int x, int t){ while(tmx[lmx]<=t-K&&lmx<=rmx){ lmx++; } while(qmx[rmx]<=x&&lmx<=rmx){ rmx--; } qmx[++rmx] = x; tmx[rmx] = t; } void push_mn(int x, int t){ while(tmn[lmn]<=t-K&&lmn<=rmn){ lmn++; } while(qmn[rmn]>=x&&lmn<=rmn){ rmn--; } qmn[++rmn] = x; tmn[rmn] = t; } int main(){ scanf("%d%d", &n, &K); for(int i = 1; i<= n; i++){ scanf("%d", &a[i]); } for(int i = 1; i<=n; i++){ push_mn(a[i], i); if(i>=K){ printf("%d ", qmn[lmn]); } } putchar('\n'); for(int i = 1; i<=n; i++){ push_mx(a[i], i); if(i>=K){ printf("%d ", qmx[lmx]); } } system("pause"); return 0; }