前言:

  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() 返回队列的后端元素

代码实现:

  1. #include<cstdio>
  2. #include<queue>
  3. using namespace std;
  4. const int maxn=1e5+;
  5. deque<int> dq;
  6. int a[maxn]={,,,,,,,,,,};
  7. int main(){
  8. dq.push_front(a[]),dq.push_front(a[]),dq.push_front(a[]);
  9. dq.push_back(a[]),dq.push_back(a[]),dq.push_back(a[]);
  10. dq.push_front(a[]),dq.push_front(a[]);
  11. dq.push_back(a[]),dq.push_back(a[]);
  12. dq.pop_front(),dq.pop_front();
  13. dq.pop_back(),dq.pop_back();
  14. int n=dq.size();//n=6
  15. for(int i=;i<=n;i++){
  16. printf("%d ",dq.front());
  17. dq.pop_front();
  18. }
  19. return ;
  20. }

deque

小结:

  双端队列不仅可以用来优化搜索,更能用来写单调队列这个神奇的xx来优化其他的一些东西(例如DP)

单调队列:

  顾名思义,单调队列是单调递增或者是单调递减的一种队列,就像一个递增队列,若将数列1 6 5 3 8放入队列中,则队列的每一步变化为:1、1 6、1 5、1 3、1 3 8 。每当放入的元素使得队列不在单调,则弹出队尾的元素,直到使得队列元素单调。

代码实现:

  1. #include<cstdio>
  2. #include<queue>
  3. using namespace std;
  4. const int maxn=1e5+;
  5. deque<int> q_up;
  6. deque<int> q_dw;
  7. int a[maxn]={,,,,,};
  8. int main(){
  9. for(int i=;i<=;i++){
  10. while(q_up.size()&&q_up.back()>=a[i])
  11. q_up.pop_back();
  12. q_up.push_back(a[i]);
  13. }
  14. int n=q_up.size();
  15. for(int i=;i<=n;i++){
  16. printf("%d ",q_up.front());
  17. q_up.pop_front();
  18. }
  19. return ;
  20. }

q_up

   当然,单调队列也可以用来维护滑动窗口的区间最大值和区间最小值。

例题_滑动窗口(洛谷P1886)

题目描述

  现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口。现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值。

  1. #include<cstdio>
  2. #include<queue>
  3. using namespace std;
  4. const int maxn=1e6+;
  5. struct cp{
  6. int ord,x;
  7. };
  8. deque<cp> q1,q2;
  9. int n,k;
  10. int a[maxn],s1[maxn],s2[maxn];
  11. inline void q_max(cp e){
  12. while(q1.size()){
  13. cp q=q1.back();
  14. if(q.x>=e.x) q1.pop_back();
  15. else break;
  16. }
  17. while(q1.size()){
  18. cp q=q1.front();
  19. if(q.ord==e.ord-k) q1.pop_front();
  20. else break;
  21. }
  22. q1.push_back(e);
  23. cp q=q1.front();
  24. if(e.ord-k>=) s1[e.ord-k+]=q.x;
  25. }
  26. inline void q_min(cp e){
  27. while(q2.size()){
  28. cp q=q2.back();
  29. if(q.x<=e.x) q2.pop_back();
  30. else break;
  31. }
  32. while(q2.size()){
  33. cp q=q2.front();
  34. if(q.ord==e.ord-k) q2.pop_front();
  35. else break;
  36. }
  37. q2.push_back(e);
  38. cp q=q2.front();
  39. if(e.ord-k>=) s2[e.ord-k+]=q.x;
  40. }
  41. inline int read(){
  42. char ch=getchar();
  43. int x=,f=;
  44. while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
  45. while(ch>=''&&ch<='') x=x*+(ch^),ch=getchar();
  46. return x*f;
  47. }
  48. int main(){
  49. n=read(),k=read();
  50. for(int i=;i<=n;i++) a[i]=read();
  51. for(int i=;i<=n;i++){
  52. cp q;
  53. q.ord=i,q.x=a[i];
  54. q_max(q),q_min(q);
  55. printf("%d ",s1[i])
  56. }
  57. for(int i=;i<=n-k+;i++) ;
  58. putchar('\n');
  59. for(int i=;i<=n-k+;i++) printf("%d ",s2[i]);
  60. return ;
  61. }

Code

  结构体类型的队列不知为何不能用 q.front().ord,所以代码显得特别冗长,如果有dalao可以解决这个问题,蒟蒻洗耳恭听!

(以上问题现已解决,附上代码)

  1. #include<cstdio>
  2. #include<queue>
  3. using namespace std;
  4. const int maxn=1e6+;
  5. struct cp{
  6. int ord,x;
  7. };
  8. deque<cp> q1,q2;
  9. int n,k;
  10. int a[maxn],s1[maxn],s2[maxn];
  11. inline void q_max(cp e){
  12. while(q1.size()&&q1.back().x>=e.x) q1.pop_back();
  13. if(q1.size()&&q1.front().ord==e.ord-k) q1.pop_front();
  14. q1.push_back(e);
  15. if(e.ord-k>=) s1[e.ord-k+]=q1.front().x;
  16. }
  17. inline void q_min(cp e){
  18. while(q2.size()&&q2.back().x<=e.x) q2.pop_back();
  19. if(q2.size()&&q2.front().ord==e.ord-k) q2.pop_front();
  20. q2.push_back(e);
  21. if(e.ord-k>=) s2[e.ord-k+]=q2.front().x;
  22. }
  23. inline int read(){
  24. char ch=getchar();
  25. int x=,f=;
  26. while(ch<''||ch>''){if(ch=='-') f=-;ch=getchar();}
  27. while(ch>=''&&ch<='') x=x*+(ch^),ch=getchar();
  28. return x*f;
  29. }
  30. int main(){
  31. n=read(),k=read();
  32. for(int i=;i<=n;i++) a[i]=read();
  33. for(int i=;i<=n;i++){
  34. cp q=(cp){i,a[i]};
  35. q_max(q),q_min(q);
  36. }
  37. for(int i=;i<=n-k+;i++) printf("%d ",s1[i]);
  38. putchar('\n');
  39. for(int i=;i<=n-k+;i++) printf("%d ",s2[i]);
  40. return ;
  41. }

Code(如果您喜欢压行)

  如有任何问题,蒟蒻洗耳恭听!

STL-Deque(双端队列)与单调队列的实现的更多相关文章

  1. [STL] deque 双端队列

  2. C++STL之双端队列容器

    C++STL之双端队列容器 deque双端队列容器与vector很类似,采用线性表顺序存储结构.但与vector区别,deque采用分块的线性存储结构来存储数据,每块的大小一般为512B,将之称为de ...

  3. deque双端队列容器

    //deque双端队列容器 //deque双端队列容器与vector一样,采用线性表顺序存储结构,但与vector不同的是, //deque采用的分块线性存储结构来存储数据,每块的大小一般为512字节 ...

  4. deque双端队列笔记

    clear()clear()clear():清空队列 pushpushpush_back()back()back():从尾部插入一个元素. pushpushpush_front()front()fro ...

  5. stl之deque双端队列容器

    deque与vector很相似,不仅能够在尾部插入和删除元素,还能够在头部插入和删除. 只是当考虑到容器元素的内存分配策略和操作性能时.deque相对vector较为有优势. 头文件 #include ...

  6. STL容器:deque双端队列学习

    所谓deque,是"double-ended queue"的缩写; 它是一种动态数组形式,可以向两端发展,在尾部和头部插入元素非常迅速; 在中间插入元素比较费时,因为需要移动其它元 ...

  7. 双端队列(单调队列)poj2823 区间最小值(RMQ也可以)

    Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 41844   Accepted: 12384 ...

  8. Java 集合深入理解(10):Deque 双端队列

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...

  9. c++ deque 双端队列

    双端队列: 函数 描述 c.assign(beg,end)c.assign(n,elem)  将[beg; end)区间中的数据赋值给c.将n个elem的拷贝赋值给c. c.at(idx)  传回索引 ...

  10. 算法-deque双端队列

    Python的deque模块,它是collections库的一部分.deque实现了双端队列,意味着你可以从队列的两端加入和删除元素 1.基本介绍 # 实例化一个deque对象d = deque()d ...

随机推荐

  1. 因网络时代与云端应用而生的AGPL-3.0授权条款

    ​ 此篇文章转载自:因應網路時代與雲端應用而生的 AGPL-3.0 授權條款 如你所见,原文为繁体,我将其转为简体并将"网路"替换为"网络",方便阅读.并未修改 ...

  2. 01@-tornado

    import tornado.web ''' tornado的基础web框架模块 ''' import tornado.ioloop ''' tornado的核心IO循环模块 封装了Linux的epo ...

  3. 开发过程中遇到的-npm加载进node_modules里的文件怎么修改

    来源:https://juejin.im/post/5ec381215188256d776342cd https://mp.weixin.qq.com/s?__biz=MzUzNjk5MTE1OQ== ...

  4. python基础 Day7

    python Day7 基础数据类型的补充 str的数据类型补充 capitalize函数将首字母大写,其余变小写 s1="taibei" print(s1.capitalize( ...

  5. CentOS 桥接网卡配置

    [root@controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0 DEVICE=br0 ONBOOT=yes TYPE=Bridge ...

  6. lx

    自我介绍:我是18软件技术5班 张震. -统计截止目前为止我自己写过代码3000行,我希望在本课结束后累计到10000行代码, 选择自测题17分,错题大多是运算符和运算符先 后级一类的题,编程题不会, ...

  7. 结对项目:四则运算题目生成器(C)

    一.Github项目地址:https://github.com/Spartaright/myapp(合作人:梁天龙.赖佑铭) 二.PSP表格(如下图) 1.项目地址 PSP表格 PSP2.1 Pers ...

  8. Combining STDP and Reward-Modulated STDP in Deep Convolutional Spiking Neural Networks for Digit Recognition

    郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 灵长类视觉系统激发了深度人工神经网络的发展,使计算机视觉领域发生了革命性的变化.然而,这些网络的能量效率比它们的生物学对 ...

  9. Linux调用Kaggle API下载数据

    1. 登录Kaggle账户,点击My Account 2. Create New API Token得到kaggle.json 3. pip install kaggle 4. 执行kaggle会报错 ...

  10. HM16.0之帧间Merge模式——xCheckRDCostMerge2Nx2N

    参考:https://blog.csdn.net/nb_vol_1/article/details/51163625 1.源代码: /** check RD costs for a CU block ...