[模板]单调队列/滑动窗口

P1886 【模板】单调队列 / 滑动窗口

单调队列中存储着具有规律的答案 根据答案的性质 按照答案的规律创建一个答案队列 只有有可能成为答案的候选项才有可能进入队列 这样的队列往往具有一一定的单调性质 、

题目描述

有一个长为 n 的序列 a,以及一个大小为 k 的窗口。现在这个窗口从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最小值和最大值。

例如,对于序列 1,3,−1,−3,5,3,6,7 以及 k=3,有如下过程:

窗口位置1 3 -1 -3 5 3 6 7 1 3 -1 -3 5 3 6 7 1 3 -1 -3 5 3 6 7 1 3 -1 -3 5 3 6 7 1 3 -1 -3 5 3 6 7 1 3 -1 -3 5 3 6 7​最小值−1−3−3−333​最大值335567​​

输入格式

输入一共有两行,第一行有两个正整数 n,k;

第二行有 n 个整数,表示序列 a。

输出格式

输出共两行,第一行为每次窗口滑动的最小值;

第二行为每次窗口滑动的最大值。

输入输出样例

输入 #1复制运行

复制代码
8 3
1 3 -1 -3 5 3 6 7

输出 #1复制运行

复制代码
-1 -3 -3 -3 3 3
3 3 5 5 6 7

说明/提示

【数据范围】

对于 50% 的数据,1≤n≤105;

对于 100% 的数据,1≤k≤n≤106,ai​∈[−231,231)。

对于这道题 一个区间上的最大值和最小值

我们可以维护一个最大值最小值队列 维护这一段的可能答案 对于最大值如果出现了一个值大于当前队列里的其他值 那么比他小的值就一定不会成为答案 那么我们可以直接弹出队列 将有可能称为答案 的候选项加入队列 也就是最大值递减 入队列 这个队列的最左端 也就是队首就是最大的 也就是这个区间的最大值

最小值同理 我们保证最小值队列单调递增 如果不符合那就不断弹出元素直到符合这一特征

对于两个队列我们要维护他们元素的有效性 删除过期的元素

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int mina[N],mint[N],maxa[N],maxt[N],maxl,maxr=1,minl=0,minr=1;
int ansmin[N],ansmax[N];
int a;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        cin>>a;
        while(maxt[maxl]<=i-k&&maxl<maxr)maxl++;
        while(mint[minl]<=i-k&&minl<minr)minl++;
        while(maxa[maxr-1]<=a&&maxr>maxl)maxr--;
        while(mina[minr-1]>=a&&minr>minl)minr--;
        maxa[maxr]=mina[minr]=a;
        maxt[maxr++]=mint[minr++]=i;
        ansmax[i]=maxa[maxl];
        ansmin[i]=mina[minl];
    }
    for(int i=k;i<=n;i++){
        cout<<ansmin[i]<<' ';
    }cout<<endl;
    for(int i=k;i<=n;i++){
        cout<<ansmax[i]<<' ';
    }cout<<endl;
    return 0;
}
相关推荐
ltl1 小时前
HNSW:图索引如何击败树索引
算法
曹牧3 小时前
C#:数字的定义和表示方式
算法·c#
Nil2083 小时前
leetcode 138随机链表的复制
算法·leetcode·链表
疯狂打码的少年5 小时前
【数据结构】图的遍历:深度优先搜索(DFS)
数据结构·笔记·算法·深度优先
-凌凌漆-6 小时前
【freertos】Task创建(v2)
java·开发语言·算法
Nil2086 小时前
leetcode 24两两交换链表中的节点
算法·leetcode·链表
.格子衫.6 小时前
033动态规划之状态压缩DP——算法备赛
算法·动态规划
ysa0510306 小时前
c++常用自带函数用法与注意
c++·笔记·算法
带多刺的玫瑰8 小时前
Leecode#4刷题之寻找两个正序数组的中位数
java·前端·算法