题目描述
现在有一堆数字共$N$个数字($N<=10^6$),以及一个大小为$k$的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and $k = 3$.
输入输出格式
输入格式:
输入一共有两行,第一行为$n,k$。
第二行为$n$个数(<INT_MAX).
输出格式:
输出共两行,第一行为每次窗口滑动的最小值
第二行为每次窗口滑动的最大值
输入输出样例
输入样例#1:
8 3 1 3 -1 -3 5 3 6 7
输出样例#1:
-1 -3 -3 -3 3 3 3 3 5 5 6 7
说明
50%的数据,$n<=10^5$
100%的数据,$n<=10^6$
题解
单调队列の模板题
然后。。。。就这样辣?
注意维护队首和插入队尾就可以了
#include <map> #include <list> #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> //#pragma GCC optimize(2) #define endl ' ' #define fast ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) using namespace std; int n,m; int q1[1000005],q2[1000005]; int a[1000005]; inline int read() //快读 { int x=0,f=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x*=10;x+=(ch-'0');ch=getchar();} return x*f; } int min_deque() { int L=1,r=0; for (register int i=1;i<=n;i++) { while (L<=r && q1[L]+m<=i) L++; while(L<=r && a[i]<a[q1[r]]) r--; q1[++r]=i; if (i>=m) cout<<a[q1[L]]<<" "; } cout<<endl; } int max_deque() { int L=1,r=0; for (register int i=1;i<=n;i++) { while (L<=r && q2[L]+m<=i) L++; while (L<=r && a[i]>a[q2[r]]) r--; q2[++r]=i; if (i>=m) cout<<a[q2[L]]<<" "; } } int main() { fast; cin>>n>>m; for (register int i=1;i<=n;i++) a[i]=read(); min_deque(); max_deque(); return 0; }