何为单调队列?

单调队列是一个队列(废话)

而且必须同时满足下标单调和值单调两个单调特性。

跟优先队列不同,优先队列直接使用堆(heap)来实现,如何删去特定下标元素?不明。

本人喜欢用单调队列存下标,这样比存值不知道高到哪里去了。

新来一个元素,进队。之后特判长度有没有超过。超过则把最前面的元素出队。

之后,如果不满足性质,就把前面的元素顶掉,直到满足性质为止。

然后才可以把队首元素拿来用。

有几个很坑的地方,具体看代码注释。

(为什么top是队尾而tail是队首?laughcry)

例题:洛谷P1886,高级模板题。还有一道剧毒的P2216。(排版很奇怪,都怪反人类的博客园☺)

AC代码:

 #include <cstdio>
const int N = ; int pl[N], l_t, l_h = , ansl[N];
int ps[N], s_t, s_h = , anss[N];
int a[N]; int main() {
int n, k;
scanf("%d%d", &n, &k);
for(int i = ; i <= n; i++) {
scanf("%d", &a[i]);
}
for(int i = ; i <= n; i++) {
pl[++l_t] = i;
ps[++s_t] = i;
if(pl[l_h] + k <= i) {
l_h++;
}
if(ps[s_h] + k <= i) {
s_h++;
}
while(l_t > l_h && a[pl[l_t - ]] <= a[i]) {
l_t--;
}
while(s_t > s_h && a[ps[s_t - ]] >= a[i]) {
s_t--;
}
pl[l_t] = i;
ps[s_t] = i;
ansl[i] = pl[l_h];
anss[i] = ps[s_h];
}
for(int i = k; i <= n; i++) {
printf("%d ", a[anss[i]]);
}
printf("\n");
for(int i = k; i <= n; i++) {
printf("%d ", a[ansl[i]]);
}
return ;
}

最新写的P1886

 #include <cstdio>
#include <algorithm>
using namespace std;
const int N=;
struct ah{int large,small;}f[N][N];
int c[N][N];
int p1[N],p2[N],top1,tail1=,top2,tail2=;///存下标
int a,b,n;///p1求min,p2求max
long long int ans=,s; int main()
{
scanf ("%d%d%d",&a,&b,&n);
for(int i=;i<=a;i++)
{
top1=top2=;
tail1=tail2=;
for(int j=;j<=b;j++)
{
scanf ("%d",&c[i][j]);
p1[++top1]=p2[++top2]=j;
while(c[i][p1[top1]]<=c[i][p1[top1-]] && top1>tail1)
{///单调队列维护
p1[top1-]=p1[top1];
top1--;
}
while(c[i][p2[top2]]>=c[i][p2[top2-]] && top2>tail2)
{
p2[top2-]=p2[top2];
top2--;
}
if(p1[top1]-p1[tail1]>=n) tail1++;///区间长度n
if(p2[top2]-p2[tail2]>=n) tail2++;
if(j>=n)
{///产生最大最小值
f[i][j-n+].large=c[i][p2[tail2]];
f[i][j-n+].small=c[i][p1[tail1]];
}
}
}
///读入完毕,处理①完毕
/*
for(int i=1;i<=a;i++)///调试
{
for(int j=1;j<=b-n+1;j++)
{
printf("%d-%d ",f[i][j].large,f[i][j].small);
}
printf("\n");
}*/ for(int j=;j<=b-n+;j++)
{
top1=top2=;
tail1=tail2=;
for(int i=;i<=a;i++)///p1 small p2 large
{
p1[++top1]=p2[++top2]=i;
while(f[p1[top1]][j].small<=f[p1[top1-]][j].small && top1>tail1)
{
p1[top1-]=p1[top1];
top1--;
}
while(f[p2[top2]][j].large>=f[p2[top2-]][j].large && top2>tail2)
{
p2[top2-]=p2[top2];
top2--;
}
if(p1[top1]-p1[tail1]>=n) tail1++;
if(p2[top2]-p2[tail2]>=n) tail2++;
if(i>=n)
{///产生最值
s=1ll*(f[p2[tail2]][j].large-f[p1[tail1]][j].small);
//printf("%d ",s);
ans=min(ans,s);
} }
//printf("\n");
}
printf("%lld",ans);
return ;
}

P2216

博客园排版有剧毒。。。

P1886 P2216 单调队列模板的更多相关文章

  1. luoguP1886 滑动窗口(单调队列模板题)

    题目链接:https://www.luogu.org/problem/P1886#submit 题意:给定n个数,求大小为k的滑动窗口中最小值和最大值. 思路:单调队列模板题. AC代码: #incl ...

  2. Sliding Window POJ - 2823 单调队列模板题

    Sliding Window POJ - 2823 单调队列模板题 题意 给出一个数列 并且给出一个数m 问每个连续的m中的最小\最大值是多少,并输出 思路 使用单调队列来写,拿最小值来举例 要求区间 ...

  3. 洛谷P1886--滑动窗口(单调队列模板)

    https://www.luogu.org/problemnew/show/P1886 单调队列的操作上比普通队列多了可以从尾端出队 单调队列保持队内元素单调递增/递减,以保证队首元素为最小/最大元素 ...

  4. hdu3415 单调队列模板题

    比较裸的单调队列 先求前缀和,枚举所有结束位置1~n+k即可 #include<iostream> #include<cstdio> #include<cstring&g ...

  5. POJ 2823 滑动窗口 单调队列模板

    我们从最简单的问题开始: 给定一个长度为N的整数数列a(i),i=0,1,...,N-1和窗长度k. 要求: f(i) = max{a(i-k+1),a(i-k+2),..., a(i)},i = 0 ...

  6. poj 2823单调队列模板题

    #include<stdio.h>//每次要吧生命值长的加入,吧生命用光的舍弃 #define N  1100000 int getmin[N],getmax[N],num[N],n,k, ...

  7. 题解【洛谷P1886】滑动窗口 /【模板】单调队列

    题面 单调队列模板题. 单调队列可以从队首和队尾出队. 队列中的元素大小具有一定的顺序. 具体可参考这一篇题解 #include <bits/stdc++.h> #define itn i ...

  8. POJ 2823 Sliding Window​ (模板题)【单调队列】

    <题目链接> <转载于>>> > 题目大意: 给你一段序列和一个长为k的窗口,这个窗口从最左边逐渐向右滑,直到滑到最右边,问你,该窗口在滑动的过程中,最大值和 ...

  9. 【模板】deque实现单调队列

    双端队列deque容器: 关于deque最常用的有这几个函数: 都是成员函数 双端队列模板题:[洛谷]P2952 [USACO09OPEN]牛线Cow Line #include<iostrea ...

随机推荐

  1. 下拉框、下拉控件之Select2

    一.Select2的功能简介 select2插件给我们带来了更加友好的交互方式,比如查询控件展开后可通过关键字进行检索 例如: Select2也可以选择带查询控件的选择框... Select2也可以选 ...

  2. outline,box-shadow,border-radius小例子

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. Spring Boot(1)——开发你的第一款Spring Boot应用(Edition1)

    Spring Boot(1)——开发你的第一款Spring Boot应用(Edition1) 准备工作: java:java 8 或者 java 9: Spring框架:5.0.8.RELEASE或以 ...

  4. llegalStateException: getWriter() has already been called for this response

    我使用Springmvc的处理器进行向AJAX传值时出现的问题 当我使用 PrintWriter out = response.getWriter();out.print("用户不存在,请先 ...

  5. python之路--触发器, 储存过程, 事务

    一. 触发器 使用触发器可以定制用户对某一张表的数据进行 [增, 删  ,改] 操作时前后的行为, (注意 没有查询),在进行增删改的时候出发的某个动作叫做 触发器. 其实就是在增删改的时候另外执行了 ...

  6. logging 实例

    import logging from logging.handlers import RotatingFileHandler import os FILE_DIR = os.path.join(os ...

  7. Memcached cas 陷阱

    本地使用的 php7环境,测试好上传到服务器后发现memcached get 报错,服务器上是php5环境: 出错代码如下: $memConnect->get($key,null, Memcac ...

  8. Ubuntu install flash

    Software&Updates - Other Software - Canonical Parners sudo apt install adobe-flashplugin

  9. hdu 5652(并查集)

    题意:很久之前,在中国和印度之间有通路,通路可以简化为一个n*m的字符串,0表示能通过,1表示障碍,每过一年就有一个坐标变成1,问你什么时候,通路彻底无法通过: 解题思路:无向图的连通性,一般直接搜索 ...

  10. 【C/C++】递归算法

    所谓递归——函数的递归调用.c语言的这种特性给程序设计带来许多方便.尤其是接触数据结构时,会发现递归的出现频率非常之高,也行之有效~下面是笔者在接触递归这个东西时的一些个人总结和体会: 1.直接或间接 ...