码迷,mamicode.com
首页 > 其他好文 > 详细

单调队列

时间:2018-08-04 22:25:21      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:原来   图片   eof   using   space   nbsp   cst   tail   例题   

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

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

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

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

两道例题:

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("\n");
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("\n");
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

 

单调队列

标签:原来   图片   eof   using   space   nbsp   cst   tail   例题   

原文地址:https://www.cnblogs.com/wxyww/p/9420207.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!