STL-Deque(双端队列)与单调队列的实现
前言:
STl是个好东西,虽然他在不开O2的条件下会跑的很慢,但他着实会让你的代码可读性大大提高,令你的代码看起来既简单又整洁。
双端队列:
顾名思义,双端队列是有两个头的,一个队首指针,一个队尾指针,先进先出或是先进后出都可以实现。
基本操作:
(1) deque<int> dq 定义一个int类型的双端队列dq
(2) deque<int> dq(15) 队列dq具有15个元素单位
(3) deque<int> dq(15,10) 队列dq内15个元素初始值均为10
(4) dq.push_back(x) 将x放入dq的末端
(5) dq.push_front(z) 将x放入dq的前端
(6) dq.size() 返回队列中元素的个数
(7) dq.pop_front() 弹出队列的前端元素
(8) dq.pop_back() 弹出队列的后端元素
(7) dq.front() 返回队列的前端元素
(8) dq.back() 返回队列的后端元素
代码实现:
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=1e5+;
deque<int> dq;
int a[maxn]={,,,,,,,,,,};
int main(){
dq.push_front(a[]),dq.push_front(a[]),dq.push_front(a[]);
dq.push_back(a[]),dq.push_back(a[]),dq.push_back(a[]);
dq.push_front(a[]),dq.push_front(a[]);
dq.push_back(a[]),dq.push_back(a[]);
dq.pop_front(),dq.pop_front();
dq.pop_back(),dq.pop_back();
int n=dq.size();//n=6
for(int i=;i<=n;i++){
printf("%d ",dq.front());
dq.pop_front();
}
return ;
}
deque
小结:
双端队列不仅可以用来优化搜索,更能用来写单调队列这个神奇的xx来优化其他的一些东西(例如DP)
单调队列:
顾名思义,单调队列是单调递增或者是单调递减的一种队列,就像一个递增队列,若将数列1 6 5 3 8放入队列中,则队列的每一步变化为:1、1 6、1 5、1 3、1 3 8 。每当放入的元素使得队列不在单调,则弹出队尾的元素,直到使得队列元素单调。
代码实现:
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=1e5+;
deque<int> q_up;
deque<int> q_dw;
int a[maxn]={,,,,,};
int main(){
for(int i=;i<=;i++){
while(q_up.size()&&q_up.back()>=a[i])
q_up.pop_back();
q_up.push_back(a[i]);
}
int n=q_up.size();
for(int i=;i<=n;i++){
printf("%d ",q_up.front());
q_up.pop_front();
}
return ;
}
q_up
当然,单调队列也可以用来维护滑动窗口的区间最大值和区间最小值。
例题_滑动窗口(洛谷P1886)
题目描述
现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=1e6+;
struct cp{
int ord,x;
};
deque<cp> q1,q2;
int n,k;
int a[maxn],s1[maxn],s2[maxn];
inline void q_max(cp e){
while(q1.size()){
cp q=q1.back();
if(q.x>=e.x) q1.pop_back();
else break;
}
while(q1.size()){
cp q=q1.front();
if(q.ord==e.ord-k) q1.pop_front();
else break;
}
q1.push_back(e);
cp q=q1.front();
if(e.ord-k>=) s1[e.ord-k+]=q.x;
}
inline void q_min(cp e){
while(q2.size()){
cp q=q2.back();
if(q.x<=e.x) q2.pop_back();
else break;
}
while(q2.size()){
cp q=q2.front();
if(q.ord==e.ord-k) q2.pop_front();
else break;
}
q2.push_back(e);
cp q=q2.front();
if(e.ord-k>=) s2[e.ord-k+]=q.x;
}
inline int read(){
char ch=getchar();
int x=,f=;
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<='') x=x*+(ch^),ch=getchar();
return x*f;
}
int main(){
n=read(),k=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++){
cp q;
q.ord=i,q.x=a[i];
q_max(q),q_min(q);
printf("%d ",s1[i])
}
for(int i=;i<=n-k+;i++) ;
putchar('\n');
for(int i=;i<=n-k+;i++) printf("%d ",s2[i]);
return ;
}
Code
结构体类型的队列不知为何不能用 q.front().ord,所以代码显得特别冗长,如果有dalao可以解决这个问题,蒟蒻洗耳恭听!
(以上问题现已解决,附上代码)
#include<cstdio>
#include<queue>
using namespace std;
const int maxn=1e6+;
struct cp{
int ord,x;
};
deque<cp> q1,q2;
int n,k;
int a[maxn],s1[maxn],s2[maxn];
inline void q_max(cp e){
while(q1.size()&&q1.back().x>=e.x) q1.pop_back();
if(q1.size()&&q1.front().ord==e.ord-k) q1.pop_front();
q1.push_back(e);
if(e.ord-k>=) s1[e.ord-k+]=q1.front().x;
}
inline void q_min(cp e){
while(q2.size()&&q2.back().x<=e.x) q2.pop_back();
if(q2.size()&&q2.front().ord==e.ord-k) q2.pop_front();
q2.push_back(e);
if(e.ord-k>=) s2[e.ord-k+]=q2.front().x;
}
inline int read(){
char ch=getchar();
int x=,f=;
while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
while(ch>=''&&ch<='') x=x*+(ch^),ch=getchar();
return x*f;
}
int main(){
n=read(),k=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++){
cp q=(cp){i,a[i]};
q_max(q),q_min(q);
}
for(int i=;i<=n-k+;i++) printf("%d ",s1[i]);
putchar('\n');
for(int i=;i<=n-k+;i++) printf("%d ",s2[i]);
return ;
}
Code(如果您喜欢压行)
如有任何问题,蒟蒻洗耳恭听!
STL-Deque(双端队列)与单调队列的实现的更多相关文章
- [STL] deque 双端队列
- C++STL之双端队列容器
C++STL之双端队列容器 deque双端队列容器与vector很类似,采用线性表顺序存储结构.但与vector区别,deque采用分块的线性存储结构来存储数据,每块的大小一般为512B,将之称为de ...
- deque双端队列容器
//deque双端队列容器 //deque双端队列容器与vector一样,采用线性表顺序存储结构,但与vector不同的是, //deque采用的分块线性存储结构来存储数据,每块的大小一般为512字节 ...
- deque双端队列笔记
clear()clear()clear():清空队列 pushpushpush_back()back()back():从尾部插入一个元素. pushpushpush_front()front()fro ...
- stl之deque双端队列容器
deque与vector很相似,不仅能够在尾部插入和删除元素,还能够在头部插入和删除. 只是当考虑到容器元素的内存分配策略和操作性能时.deque相对vector较为有优势. 头文件 #include ...
- STL容器:deque双端队列学习
所谓deque,是"double-ended queue"的缩写; 它是一种动态数组形式,可以向两端发展,在尾部和头部插入元素非常迅速; 在中间插入元素比较费时,因为需要移动其它元 ...
- 双端队列(单调队列)poj2823 区间最小值(RMQ也可以)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 41844 Accepted: 12384 ...
- Java 集合深入理解(10):Deque 双端队列
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...
- c++ deque 双端队列
双端队列: 函数 描述 c.assign(beg,end)c.assign(n,elem) 将[beg; end)区间中的数据赋值给c.将n个elem的拷贝赋值给c. c.at(idx) 传回索引 ...
- 算法-deque双端队列
Python的deque模块,它是collections库的一部分.deque实现了双端队列,意味着你可以从队列的两端加入和删除元素 1.基本介绍 # 实例化一个deque对象d = deque()d ...
随机推荐
- 【工具】OSS阿里云存储服务--超级简单--个人还是觉得Fastdfs好玩
介绍 阿里云对象存储服务(Object Storage Service,简称 OSS)为您提供基于网络的数据存取服务. 使用 OSS,您可以通过网络随时存储和调用包括文本.图片.音频和视频等在内的各种 ...
- [源码分析]ArrayList和LinkedList如何实现的?我看你还有机会!
文章已经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所需要掌握的核心知识,欢迎Star和指教. 欢迎关注我的公众号,文章每周更新. 前言 说真的,在 Jav ...
- Navicat15破解+网盘位置
百度网盘Navicat.15位置 链接:https://pan.baidu.com/s/1Vn0Qnt8IUA37a-p4hAnk5g 提取码:clq3 1.百度网盘下载完后,点这个安装Navicat ...
- DP搬运工1 [来自yyy--mengbier的预设型dp]
DP搬运工1 题目描述 给你 \(n,K\) ,求有多少个 \(1\) 到 \(n\) 的排列,满足相邻两个数的 \(max\) 的和不超过 \(K\). 输入格式 一行两个整数 \(n,K\). 输 ...
- Java并发篇
Java并发篇 作者:星晴(当地小有名气,小到只有自己知道的杰伦粉) 1. Java锁 1.1 乐观锁 1.2 悲观锁 1.3 自旋锁 1.4 Synchronized 同步锁 1.4.1 核心组件 ...
- anaconda下载包时网络连接错误的解决方法(CondaHTTPError:HTTP 000 connection failed for url)
继上一篇<在WSL上搭载python编程环境>之后,下载软件和创建新环境的过程非常艰辛,下载太慢,以至于常常中断. 不论用conda安装一些python的包,还是创新独立的编程环境时,出现 ...
- golang 判断前缀后缀、包含关系
HasPrefix 判断字符串 s 是否以 prefix 开头:strings.HasPrefix(s, prefix string) bool HasSuffix 判断字符串 s 是否以 suffi ...
- go genetlink demo
原文链接:https://github.com/mdlayher/genetlink [root@wangjq test]# cat genetlink.go package main import ...
- Spring Security自定义认证页面(动态网页解决方案+静态网页解决方案)--练气中期圆满
写在前面 上一回我们简单分析了spring security拦截器链的加载流程,我们还有一些简单的问题没有解决.如何自定义登录页面?如何通过数据库获取用户权限信息? 今天主要解决如何配置自定义认证页面 ...
- 算法-搜索(6)B树
B树是平衡的m路搜索树. 根结点至少两个子女,根结点以外的非失败结点至少⌈m/2⌉个子女,所有失败结点都在h+1层. 第h层至少2⌈m/2⌉h-1个结点,因此失败结点数n+1≥2⌈m/2⌉h-1个. ...