单调队列

Posted wxyww

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调队列相关的知识,希望对你有一定的参考价值。

 单调队列就是维护一个队列,使得该队列从队首到队尾成单调递增或是单调递减。

 做法就是每向队列里加入一个元素就判断该元素是不是比队尾元素大(以递减序列为例),是的话就将队尾元素出列,直到该元素比队尾元素小,然后将该元素放置队尾。

  这么久了一直不明白单调队列的实现,现在看来,原来这么简单。。。。。

  单调栈的原理相似,只不过一个是栈,一个是队列而已

两道例题:

luogu1886

luogu1714

 

 

代码:

 

技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=1000000*2;
 6 int q[N],head,tail,bz[N];
 7 int a[N],n,pos[N],k;
 8 int main()
 9 {
10   scanf("%d%d",&n,&k);
11   for(int i=1;i<=n;++i)
12     scanf("%d",&a[i]);
13     if(k==1)//日常卡数据,请忽略
14     {
15       for(int i=1;i<=n;++i)
16       printf("%d ",a[i]);
17       printf("
");
18       for(int i=1;i<=n;++i)
19       printf("%d ",a[i]);
20       return 0;
21     }
22   q[++tail]=a[1];pos[tail]=1;
23   for(int i=2;i<k;++i)
24   {
25     while(a[i]<q[tail]&&tail>head) --tail;
26     q[++tail]=a[i];
27     pos[tail]=i;
28   }
29   for(int i=k;i<=n;++i)
30   {
31     bz[i-k]=1;
32     while(bz[pos[head]]==1) head++;
33      while((a[i]<q[tail]||bz[pos[tail]])&&tail>=head)
34     --tail;
35     q[++tail]=a[i];
36     pos[tail]=i;
37     printf("%d ",q[head]);
38   }
39   printf("
");
40   memset(q,0,sizeof(q));
41   memset(bz,0,sizeof(bz));
42   memset(pos,0,sizeof(pos));
43   tail=1;head=1;
44   q[++tail]=a[1];pos[tail]=1;
45   for(int i=2;i<k;++i)
46   {
47     while(a[i]>q[tail]&&tail>=head) --tail;
48     q[++tail]=a[i];
49     pos[tail]=i;
50   }
51   for(int i=k;i<=n;++i)
52   {
53     bz[i-k]=1;
54     while(bz[pos[head]]==1) head++;
55      while((a[i]>q[tail]||bz[pos[tail]])&&tail>=head)
56     --tail;
57     q[++tail]=a[i];
58     pos[tail]=i;
59     printf("%d ",q[head]);
60   }
61   return 0;
62 }
luogu1886
技术分享图片
 1 #include<cstdio>
 2 #include<iostream>
 3 using namespace std;
 4 int n,m;
 5 const int N=500000*2;
 6 int bz[N],pos[N],a[N],q[N],sum[N];
 7 int head=1,tail=0,ans=-0x7fffffff;
 8 int main()
 9 {
10   scanf("%d%d",&n,&m);
11   for(int i=1;i<=n;++i)
12   {
13     scanf("%d",&a[i]);
14     sum[i]=a[i]+sum[i-1];
15   }
16   m++;
17   for(int i=1;i<=n;++i)
18   {
19     if(i>m) bz[i-m]=1;
20     while(bz[pos[head]]) head++;
21     while((sum[i]<q[tail]||bz[pos[tail]])&&tail>=head) tail--;
22     q[++tail]=sum[i];
23     pos[tail]=i;
24     ans=max(ans,sum[i]-q[head]);
25   }
26   printf("%d",ans);
27   return 0;
28 }
luogu1714

 

以上是关于单调队列的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6957 Maximal submatrix(悬线法 || 优先队列 || 单调栈 )

POJ 2823 Sliding Window 单调队列

单调队列与单调栈作用

单调队列题目练习

POJ 2823 Sliding Window(单调队列)

单调队列单调栈优先队列模板