何为单调队列?

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

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

跟优先队列不同,优先队列直接使用堆(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. 记录SSM框架项目迁移SpringBoot框架-----pom.xml的迁移

    第一步:迁移pom.xml文件(去除spring相关的依赖) SSM中的pom: <project xmlns="http://maven.apache.org/POM/4.0.0&q ...

  2. 重写TreeView模板来实现数据分层展示(一)

    总想花些时间来好好总结一下TreeView这个WPF控件,今天来通过下面的这几个例子来好好总结一下这个控件,首先来看看一个常规的带虚线的TreeView控件吧,在介绍具体如何完成之前首先来看看最终实现 ...

  3. 接触Struts2的ModelDriven<>接口

    最近在学SSH框架,实战项目,用到了Struts2的ModelDriven<>接口,在这做一点记录 ModelDriven,意为模型驱动,意思是直接把实体类当成页面数据的收集对象 参考他人 ...

  4. MySQL in型子查询陷阱

    现在有两个表,table1和table2,table1有1千万数据(id 主键索引),table2有三条数据(uid字段 3,5,7): select * from table1 where id i ...

  5. 当进行数据查询时候 要考虑创建一个model ;具备传入与输出的字段

    当进行数据查询时候 要考虑创建一个model ;具备传入与输出的字段

  6. cookie中的小错误

    今天在练习 cookie时意外的报了这个错. 这句话的意思是一个不识别的字符[32]出现在了cookie当中由于tomcat的版本比较高,所以在addCookie时是不能使用空格的 而在ASCII码中 ...

  7. Python介绍及环境配置

    Python 简介 Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有 ...

  8. 删除本地git的远程分支和远程删除git服务器的分支【转】

    转- 删除本地git的远程分支和远程删除git服务器的分支 在项目中使用git管理代码后,有些时候会创建很多不同名称的分支,以此区分各个分支代码功能. 而随着代码的合并,以前的分支就可能不再需要保存了 ...

  9. 关于jQuery.when()用法

    1.该方法在jQuery1.5开始被引入. 2.用法测试 a. var url1 = "/resource/ar/hometab/index_tab_games.json", ur ...

  10. ng-click 发两次ajax请求的原因及解决方法

    http://blog.csdn.net/anmo/article/details/17083125