单调队列
Posted wxyww
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调队列相关的知识,希望对你有一定的参考价值。
单调队列就是维护一个队列,使得该队列从队首到队尾成单调递增或是单调递减。
做法就是每向队列里加入一个元素就判断该元素是不是比队尾元素大(以递减序列为例),是的话就将队尾元素出列,直到该元素比队尾元素小,然后将该元素放置队尾。
这么久了一直不明白单调队列的实现,现在看来,原来这么简单。。。。。
单调栈的原理相似,只不过一个是栈,一个是队列而已
两道例题:
代码:
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 }
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 }
以上是关于单调队列的主要内容,如果未能解决你的问题,请参考以下文章