参考博客https://www.cnblogs.com/tham/p/8038828.html

例题  poj 2823

                                       Sliding Window
Time Limit: 12000MS   Memory Limit: 65536K
Total Submissions: 67137   Accepted: 19061
Case Time Limit: 5000MS

Description

An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example: 
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

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line. 

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values. 

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 题意 给出一个序列 n个数 求每个长度为k的子串的最大值和最小值
解析 如果用尺取写的话 失匹的话就要花费o(k)的复杂度去维护最大值 最小值 总时间复杂度o(n*k) 数据卡的死就肯定超时
    我们发现维护最大最最小值的时候 发现有很多重复的比较 所以我们可以维护一个最值数组 使它严格单调 这样直接取第一个元素就好了(单调队列)。
    
AC代码(c++)
 #include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <vector>
using namespace std;
const int maxn = 1e6+;
const int inf = 0x3f3f3f3f,mod = ;
const double epx = 1e-;
typedef long long ll;
struct node
{
int x,y; //x值 y下标
}v[maxn];
int a[maxn],mn[maxn],mx[maxn];
int n,m;
void getmin()
{
int head=,tail=;
for(int i=;i<m;i++)
{
while(head<=tail&&a[i]<=v[tail].x)tail--;
v[++tail].x=a[i],v[tail].y=i;
}
for(int j=m;j<=n;j++)
{
while(head<=tail&&a[j]<=v[tail].x)tail--;
v[++tail].x=a[j],v[tail].y=j;
while(j-v[head].y>=m)head++;
mn[j]=v[head].x;
}
}
void getmax()
{
int head=,tail=;
for(int i=;i<m;i++)
{
while(head<=tail&&a[i]>=v[tail].x)tail--;
v[++tail].x=a[i],v[tail].y=i;
}
for(int j=m;j<=n;j++)
{
while(head<=tail&&a[j]>=v[tail].x)tail--;
v[++tail].x=a[j],v[tail].y=j;
while(j-v[head].y>=m)head++;
mx[j]=v[head].x;
}
}
int main()
{
scanf("%d %d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
getmax();
getmin();
for(int i=m;i<=n;i++)
{
printf(i!=n?"%d ":"%d\n",mn[i]);
}
for(int i=m;i<=n;i++)
{
printf(i!=n?"%d ":"%d\n",mx[i]);
}
}
												

单调队列&单调栈 基础的更多相关文章

  1. 单调队列 && 单调栈

    单调队列 && 单调栈 单调队列 维护某个滑动区间的min or max,可用于dp的优化 以维护min为例,采用STL双端队列实现 每次加入元素x前 先检查队首元素==滑动后要删除的 ...

  2. 联赛模拟测试18 A. 施工 单调队列(栈)优化DP

    题目描述 分析 对于 \(Subtask\ 1\),可以写一个 \(n^3\) 的 \(DP\),\(f[i][j]\) 代表第 \(i\) 个建筑高度为 \(j\) 时的最小花费,随便转移即可 时间 ...

  3. 数据结构录 之 单调队列&单调栈。

    队列和栈是很常见的应用,大部分算法中都能见到他们的影子. 而单纯的队列和栈经常不能满足需求,所以需要一些很神奇的队列和栈的扩展. 其中最出名的应该是优先队列吧我觉得,然后还有两种比较小众的扩展就是单调 ...

  4. 单调队列&单调栈

    单调队列 例题: Poj 2823给定一个数列,从左至右输出每个长度为m的数列段内的最小数和最大数.数列长度:N<=106,m<=N 对于单调队列,我们这样子来定义: 1.维护区间最值 2 ...

  5. 数据结构录 之 单调队列&单调栈。(转)

    http://www.cnblogs.com/whywhy/p/5066306.html 队列和栈是很常见的应用,大部分算法中都能见到他们的影子. 而单纯的队列和栈经常不能满足需求,所以需要一些很神奇 ...

  6. 大视野 1012: [JSOI2008]最大数maxnumber(线段树/ 树状数组/ 单调队列/ 单调栈/ rmq)

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 9851  Solved: 4318[Submi ...

  7. 小Z爱序列(NOIP信(sang)心(bin)赛)From FallDream(粗制单调队列&单调栈的算法解析)

    原题: 小Z最擅长解决序列问题啦,什么最长公共上升然后下降然后上升的子序列,小Z都是轻松解决的呢. 但是小Z不擅长出序列问题啊,所以它给了你一道签到题. 给定一个n个数的序列ai,你要求出满足下述条件 ...

  8. POJ 3494 Largest Submatrix of All 1’s 单调队列||单调栈

    POJ 3494 Largest Submatrix of All 1’s Description Given a m-by-n (0,1)-matrix, of all its submatrice ...

  9. 单调队列&单调栈归纳

    单调队列 求长度为M的区间内的最大(小)值 单调队列的基本操作,也就是经典的滑动窗口问题. 求长度为M的区间内最大值和最小值的最大差值 两个单调队列,求出长度为M的区间最大最小值的数组,分别求最大最小 ...

随机推荐

  1. c#.net 正则匹配以特定字符串开头,以特定字符串结尾

    string[] unit = Getunit(result40, "(?<=(开始字符串))[.\\s\\S]*?(?=(结束字符串))"); private string ...

  2. Java多线程——线程的优先级和生命周期

    Java多线程——线程的优先级和生命周期 摘要:本文主要介绍了线程的优先级以及线程有哪些生命周期. 部分内容来自以下博客: https://www.cnblogs.com/sunddenly/p/41 ...

  3. vuetifyjs简介及其使用

    何为 vuetify 一个vue ui库,提供vue组件供使用.根据 Google Material Design 指南实现(https://material.io/).Vuetify支持SSR(服务 ...

  4. sql 关键字的用法

    coalesce( T.GoodsCode,'0') 若 T.GoodsCode 为NULL 这 用0替换 round(S.SaleEarning,2) 保留两位小数 SUBSTRING(zb.acc ...

  5. Youtube-dl 简短使用总结

    默认下载bestvideo+bestaudio,并通过ffmpeg -c copy output.mp4 简单的封装进mp4格式,而不进行转码. 有时候bestaudio 是opus编码的,但是mp4 ...

  6. PHP文件及目录考察点

    文件读取/写入操作 fopen()函数 用来打开一个文件,打开时需要指定打开模式 打开模式 模式 |作用 --- |--- 'r' |只读方式打开,将文件指针指向文件头. 'r+' |读写方式打开,将 ...

  7. 一起来学SpringBoot(十七)优雅的参数校验

    参数校验在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动方法内代码显得冗长每次要看哪些参数 ...

  8. oracle 时区

    select sysdate from dual;select systimestamp from dual;select localtimestamp from dual;select curren ...

  9. cat - 连接文件并在标准输出上输出

    SYNOPSIS 总览 cat [选项列表] [文件列表]... DESCRIPTION 描述 将文件列表中的文件或标准输入连接到标准输出. -A, --show-all 等价于 -vET . -b, ...

  10. Codeforces Round #569 题解

    Codeforces Round #569 题解 CF1179A Valeriy and Deque 有一个双端队列,每次取队首两个值,将较小值移动到队尾,较大值位置不变.多组询问求第\(m\)次操作 ...