双端队列(单调队列)poj2823 区间最小值(RMQ也可以)
Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 41844 | Accepted: 12384 | |
Case Time Limit: 5000MS |
Description
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
- 8 3
- 1 3 -1 -3 5 3 6 7
Sample Output
- -1 -3 -3 -3 3 3
- 3 3 5 5 6 7
双端队列介绍:
deque和vector一样都是标准模板库中的内容,deque是双端队列,在接口上和vector非常相似,在许多操作的地方可以直接替换。假如读者已经能够有效地使用vector容器,下面提供deque的成员函数和操作,进行对比参考。
deque<type>q;
q.empty():判断队列是否为空
q.front() ,q.back() 队列的首元素和尾元素
q.begin() ,q.end() 返回队列首元素和结尾地址
q.push_front() ,q.push_back() 分别在队首和队尾插入元素
q.pop_front() ,q.pop_back() 删除首元素和尾元素
q.size() 返回容器中元素的个数
q.clear() 清空所有元素
本题最好采用模拟队列,缩短时限,分析怎样维护递增单调队列,开一个结构体要有id序号,和v值两个内容,首先当队列为空的时候,加入第一个元素;对于下一个将要加入的元素,把该元素a的大小和队尾的元素大小tail进行比较,如果a>tail,则移除尾元素,继续比较,直到a<=tail时把a加入到队列的尾部,当k个连续的数列向后移动时,队列中的前面的元素可能已经不再此范围内了,所以还要判断首元素的序号是不是在此时的范围内,如果不在,这删除首元素(即head++)直到满足条件为止,这样便可以维护一个单调递增队列
当维护单调递减序列的道理同上
程序:
- #include"cstdio"
- #include"cstring"
- #include"cstdlib"
- #include"cmath"
- #include"string"
- #include"map"
- #include"cstring"
- #include"algorithm"
- #include"iostream"
- #include"set"
- #include"queue"
- #include"stack"
- #define inf 1000000000000
- #define M 1000009
- #define LL long long
- #define eps 1e-12
- #define mod 1000000007
- #define PI acos(-1.0)
- using namespace std;
- int a[M],maxi[M],mini[M];
- struct node
- {
- int v,id;
- node(){}
- node(int id,int v)
- {
- this->v=v;
- this->id=id;
- }
- }qmin[M*2],qmax[M*2];
- int main()
- {
- int n,k;
- while(scanf("%d%d",&n,&k)!=-1)
- {
- int minhead=0,mintail=0;
- int maxhead=0,maxtail=0;
- int cnt=0;
- for(int i=1;i<=n;i++)
- {
- scanf("%d",&a[i]);
- if(i<=k)
- {
- while(mintail>minhead&&a[i]<qmin[mintail-1].v)
- {
- mintail--;
- }
- qmin[mintail++]=node(i,a[i]);//把前k个元素入队
- while(maxtail>maxhead&&a[i]>qmax[maxtail-1].v)
- {
- maxtail--;
- }
- qmax[maxtail++]=node(i,a[i]);
- }
- }
- mini[cnt]=qmin[minhead].v;
- maxi[cnt++]=qmax[maxhead].v;
- for(int i=k+1;i<=n;i++)
- {
- while(mintail>minhead&&a[i]<qmin[mintail-1].v)//删除比a[i]小的尾元素
- {
- mintail--;
- }
- qmin[mintail++]=node(i,a[i]);
- while(mintail>minhead&&i-k>=qmin[minhead].id)//删除不再范围内的首元素
- {
- minhead++;
- }
- while(maxtail>maxhead&&a[i]>qmax[maxtail-1].v)
- {
- maxtail--;
- }
- qmax[maxtail++]=node(i,a[i]);
- while(maxtail>maxhead&&i-k>=qmax[maxhead].id)
- {
- maxhead++;
- }
- mini[cnt]=qmin[minhead].v;
- maxi[cnt++]=qmax[maxhead].v;
- }
- printf("%d",mini[0]);
- for(int i=1;i<cnt;i++)
- printf(" %d",mini[i]);
- printf("\n%d",maxi[0]);
- for(int i=1;i<cnt;i++)
- printf(" %d",maxi[i]);
- printf("\n");
- }
- return 0;
- }
双端队列(单调队列)poj2823 区间最小值(RMQ也可以)的更多相关文章
- Java数据结构——用双端链表实现队列
//================================================= // File Name : LinkQueue_demo //---------------- ...
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- 与图论的邂逅01:树的直径&基环树&单调队列
树的直径 定义:树中最远的两个节点之间的距离被称为树的直径. 怎么求呢?有两种官方的算法(不要问官方指谁我也不晓得): 1.两次搜索.首先任选一个点,从它开始搜索,找到离它最远的节点x.然后从x开始 ...
- Sliding Window - 题解【单调队列】
题面: An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving fr ...
- [洛谷P1886]滑动窗口 (单调队列)(线段树)
---恢复内容开始--- 这是很好的一道题 题目描述: 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口. 现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的 ...
- POJ3162 Walking Race(树形DP+尺取法+单调队列)
题目大概是给一棵n个结点边带权的树,记结点i到其他结点最远距离为d[i],问d数组构成的这个序列中满足其中最大值与最小值的差不超过m的连续子序列最长是多长. 各个结点到其他结点的最远距离可以用树形DP ...
- 51nod 1050 循环数组最大子段和 单调队列优化DP
题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1050 这个呢,这个题之前 求一遍最大值 然后求一遍最小值 ...
- Second My Problem First HDU - 3706 单调队列
单调队列 单调队列是指一个队列内部的元素具有严格单调性的一种数据结构,分为单调递增队列和单调递减队列. 单调队列满足两个性质 1.单调队列必须满足从队头到队尾的严格单调性. 2.排在队列前面的比排在队 ...
- P1886 滑动窗口 /【模板】单调队列 方法记录
原题链接 滑动窗口 /[模板]单调队列 题目描述 有一个长为 \(n\) 的序列 \(a\),以及一个大小为 \(k\) 的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最 ...
随机推荐
- flex mxmlc 手动编译项目
首先: 1.下载flex的sdk,如果你电脑有装flash builder,它自带了一份,位于安装目录的sdks目录下. 备注:(sdk依赖java的jre) 2.配置mxmlc的java运行环境jr ...
- Android 的上下文菜单: Context Menu,registerForContextMenu(getListView())
概述: Android 的上下文菜单类似于 PC 上的右键菜单.当为一个视图注册了上下文菜单之后,长按(2 秒左右)这个视图对象就会弹出一个浮动菜单,即上下文菜单.任何视图都可以注册上下文菜单,不过, ...
- XMLHttpRequest函数
function createXmlHttpRequest(){ if(window.ActiveXObject){ return new ActiveXObject("Microsoft. ...
- HBase的完全分布式的搭建与部署,以及多master
一:前提准备 1.设置时间同步 2.清空logs,datas 3.格式化集群 bin/hdfs namenode -format 4.重启集群 sbin/start-dfs.sh sbin/start ...
- SimpleUrlHandlerMapping 使用
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- JavaSE的知识
一 SE的知识体系: java基础: 一基础语法 8个基本数据类型-->8个包装类 数据类型转换: 自动转换(从小到大) 强制转换(从大到小) 注意:int 和char 分支与判断: if(){ ...
- angularJS自定义指令模板替换
<html> <head> <meta charset="utf-8"/> <title></title> </h ...
- linux pipe
1. 函数说明 pipe(建立管道): 1) 头文件 #include<unistd.h> 2) 定义函数: int pipe(int filedes[2]); 3) 函数说明: pipe ...
- [LeetCode]题解(python):092 Reverse Linked List II
题目来源 https://leetcode.com/problems/reverse-linked-list-ii/ Reverse a linked list from position m to ...
- DDS杂散频谱来源:谐波超Nyquist 折返