https://www.luogu.org/problem/P1886
题目描述
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.
输入格式
输入一共有两行,第一行为n,k。
第二行为n个数(<INT_MAX).
输出格式
输出共两行,第一行为每次窗口滑动的最小值
第二行为每次窗口滑动的最大值
填个高一时的坑
单调队列维护一下
#include<iostream> #include<cstdio> #define ri register int #define u int namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&s<='9') { x=(x<<1)+(x<<3)+s-'0'; s=getchar(); } return x*f; } } using opt::in; #define NN 1000005 namespace mainstay { u N,K,l[2],r[2],ans[NN][2]; struct node{ u x,dic; }q[NN][2]; inline void solve(){ N=in(),K=in(); for(ri i(1);i<=N;++i){ u _a(in()); while(r[0]-1>=l[0]&&q[r[0]][0].x>=_a) --r[0]; while(r[1]-1>=l[1]&&q[r[1]][1].x<=_a) --r[1]; q[++r[0]][0].x=_a,q[r[0]][0].dic=i; q[++r[1]][1].x=_a,q[r[1]][1].dic=i; while(l[0]+1<=r[0]&&q[l[0]+1][0].dic<i-K+1) ++l[0]; while(l[1]+1<=r[1]&&q[l[1]+1][1].dic<i-K+1) ++l[1]; ans[i][0]=q[l[0]+1][0].x,ans[i][1]=q[l[1]+1][1].x; } for(ri i(K);i<=N;++i) printf("%d ",ans[i][0]); printf("\n"); for(ri i(K);i<=N;++i) printf("%d ",ans[i][1]); } } int main() { //freopen("x.txt","r",stdin); mainstay::solve(); }