博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单调队列
阅读量:6374 次
发布时间:2019-06-23

本文共 1863 字,大约阅读时间需要 6 分钟。

单调队列

今天问了长者有关单调队列的知识,单调队列这种东西其实用途并不是特别的广泛,只是在处理区间上询问的时候比较管用,而且这种询问有限制,比如:

一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值。若前面的数不足m项则从第1个数开始,若前面没有数则输出0。
这种类似的题目,每次询问前m个数中最小的,显然暴力的话是O(n * m)的每个点枚举一遍m,就是这样,但是暴力显然会TLE,那有什么办法呢?
RMQ是可以的,但是有一个问题,就是MLE,2000000 * 20,会炸空间,线段树显然是可以的,但是还不是最优的。所以我们引出单调队列这种东西,解决序列上滑块的问题(m这个区间在序列上动来动去,就像是个滑块^_^).

单调队列?

我们制作一个严格上升或下降的队列,它的队首是你处理当前区间的最大(最小)值,然后进行删除和加入的操作。

加入: 我们假设有8,1,2,3,7,9,6.这样的一个序列,我们想要一个单调上升的序列,这样就可以保证队首是最小的。我们加入元素的时候我们要存下每个值在原序列中的下标,因为,我们只有处理[i-m,i]这样的一个区间,如果队首元素的下标不在这个区间,显然就毫无意义了不。好,我们开始加入元素,我们每次添加元素,从队尾开始比较,直到找到比它小的数替换掉。
假设没有删除操作
第一次 :8
第二次:1(1 < 8 所以 我们替换掉8)
第三次:1,2.
第四次:1,2,3.
第五次:1,2,3,7.
第六次:1,2,3,7,9.
第七次:1,2,3,6.(跟7,9,比较都小,所以替换,尾指针直到6的位置)。

删除

删除其实很简单,我们比较队首的下标如果不在范围内直接删掉。

#include
#include
#include
#include
#include
#include
using namespace std;#define REP(i,a,b) for(register int i = (a), i##_end_ = (b); i <= i##_end_ ; ++i)inline int read(){ char c = getchar();register int fg = 1,sum = 0; while(c < '0' || c > '9') { if(c == '-')fg = -1; c = getchar(); } while(c >= '0' && c <= '9') { sum =sum * 10 + c - '0'; c = getchar(); } return fg * sum;}const int maxn = 2000000+10;struct T{ int val,pos;};struct que{ int l,r; T a[maxn]; que(){l = 1, r = 0;} inline void putin(T x)//加入 { while(r >= l && a[r].val > x.val)r--; a[++r] = x; } inline void pop(int pos)//删除 { while(r >= l && a[l].pos < pos)l++; } void print() { for(int i=l;i<=r;i++) printf("%d ",a[i].val); printf("\n"); } inline int top() { return a[l].val;}}q;int n,m,f[maxn];int main(){ n = read(),m = read(); REP(i,1,n)f[i] = read(); puts("0"); q.putin((T){f[1],1}); REP(i,2,n) { q.print(); if(i-m>=0)q.pop(i-m); printf("%d\n",q.top()); q.putin((T){f[i],i}); } return 0;}

转载于:https://www.cnblogs.com/brodrinkwater/p/7527986.html

你可能感兴趣的文章
android EditText inputType说明
查看>>
交叉熵代价函数(作用及公式推导)
查看>>
这个用markdown编写
查看>>
display、 float 、position
查看>>
centos7.4 安装LAMP环境
查看>>
poj 1821 Fence(单调队列)
查看>>
关于Map集合的遍历总结
查看>>
【计数】【UVA11401】 Triangle Counting
查看>>
Django建站纪要(一)——做个blog
查看>>
(实现)vue.js最简实现
查看>>
RabbitMQ发送消息成功,但是接受不到消息
查看>>
nova-network创建初始化网络
查看>>
虎符遥控器(PPT遥控翻页)
查看>>
Java常用缩略词
查看>>
Java构造块,静态代码块,构造方法执行顺序
查看>>
3D打印开源切片软件Cura配置步骤
查看>>
c++读取TXT文件内容
查看>>
EF Core使用CodeFirst在MySql中创建新数据库以及已有的Mysql数据库如何使用DB First生成域模型...
查看>>
[android] ndk环境的搭建
查看>>
Kafka集群搭建
查看>>