洛谷P1886 滑动窗口 单调队列
洛谷P1886 滑动窗口
单调队列 求一个固定长度的区间 最小值和最大值
单调队列求最小值时
1、刚要插入一个数 判断 其是否 小于等于 队尾的数
如果是 则将队尾的数出队 因为求的是队尾到之前的
最小值 ,所以其已经不可能成为 最小值了
2、然后数字进队
3、如果队头 已经不再这个区间中,那就队头出队
最大值也是同理
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <string> 6 #include <iomanip> 7 #include <iostream> 8 #include <algorithm> 9 using namespace std ; 10 11 const int maxn = 1000011 ; 12 struct node{ 13 int val,id ; 14 }; 15 int n,k,h,t,tot ; 16 int Q[maxn],ans[maxn],p[maxn] ; 17 int a[maxn] ; 18 19 int main() 20 { 21 scanf("%d%d",&n,&k) ; 22 for(int i=1;i<=n;i++) scanf("%d",&a[ i ]) ; 23 h = 1 ; t = 0 ; 24 for(int i=1;i<=n;i++) 25 { 26 while( h<=t&&Q[ t ] >= a[ i ] ) t-- ; 27 Q[++t] = a[ i ] ; 28 p[ t ] = i ; 29 while( h<=t&&p[ t ]-p[ h ]+1 > k) h++ ; 30 31 if(i>=k) ans[++tot] = Q[ h ] ; 32 } 33 for(int i=1;i<=tot;i++) printf("%d ", ans[ i ] ) ; 34 printf("\n") ; 35 36 37 tot = 0 ; 38 h = 1 ; t = 0 ; 39 for(int i=1;i<=n;i++) 40 { 41 while(h<=t&&Q[t] <= a[ i ]) t-- ; 42 Q[++t] = a[ i ] ; 43 p[ t ] = i ; 44 while(h<=t&&p[t]-p[h]+1>k) h++ ; 45 if(i>=k) ans[++tot] = Q[ h ] ; 46 } 47 for(int i=1;i<=tot;i++) printf("%d ",ans[ i ]) ; 48 49 50 51 return 0 ; 52 }