首页 > 代码库 > 洛谷P1886 滑动窗口 单调队列

洛谷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 }

 

洛谷P1886 滑动窗口 单调队列