单调队列

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

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

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

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

两道例题:

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

 

全部评论

相关推荐

头像
03-03 13:17
已编辑
苏州大学 Java
面试官真的很有耐心,人非常nice,但问得也是真的很细。面完半小后约HR面。有没有人说说HR面会问啥?【希望能过吧,以前真没想到面个试这么耗精力,这一周感觉都被掏空了】1.请做一下自我介绍。2.你掌握的数据结构有哪些?3.请讲一下一致性哈希的原理和解决的问题。4.请讲一下Ring&nbsp;buffer(环形缓冲区)的相关内容。5.请讲解一下HTTP状态码的相关分类和含义(如2xx、3xx、4xx、5xx)。6.请讲解一下四层网络负载均衡和七层网络负载均衡的区别,以及各自的应用场景。7.请讲一下反向代理的原理和常用工具,以及正向代理的相关内容。8.进程间通信的方式有哪些?哪种方式效率更高,为什么?9.请讲一下MySQL主从复制的实现原理(基于binlog、redolog相关)。10.多个从节点之间出现数据不一致的问题该如何解决?11.你了解的消息中间件有哪些?RabbitMQ、RocketMQ、Kafka这三种消息中间件的区别是什么?12.Redis中最常用的数据结构有哪些?13.请讲一下Redis中Zset(sorted&nbsp;set)的底层实现和优化策略。14.什么是小哈希和大哈希,二者在查找、插入性能上有什么区别?15.请讲一下TCC分布式事务算法的相关内容,以及它和2PC、3PC的区别。16.你在项目中使用的服务发现组件是什么,它的实现原理是什么?17.你在项目中使用的序列化协议是什么,为什么选择该协议?18.长连接的适用场景是什么?哪些场景不适合使用长连接,原因是什么?19.请设计一个评论系统(包括数据库表设计、数据结构、关联关系等)。20.【反问】想具体知道会做哪些模块的工作?有没有导师?
百特曼3:节子还是一如既往的八股大厂
查看78道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务