码迷,mamicode.com
首页 > 其他好文 > 详细

单调队列

时间:2019-08-02 16:16:44      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:||   deque   滑动窗口   插入   string   例题   http   last   etc   

单调队列

一、定义

        单调队列里的元素是单调递增或者单调递减的

 

二、实现

双端队列 deque

支持操作:(1)询问队首/队尾元素   front / back

                  (2)从队首/队尾删除元素  pop_front() / pop_back()

                  (3)从队首/队尾插入元素  push_front() / push_back()

 

三、例题

1.P1886 滑动窗口

题解

以求最小值为例,队列里的元素必须是单调递增的,保证队首是答案,我们每次输出队首

新加入一个元素,如果使得队列非递增,就把前面比他大的全弹出队列

一旦队首元素过了期,也就是窗口划过了它,我们就弹出队首,反正我们还会得到一个新的ans

该输出就输出就行了

 

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstdlib>                                                                             

using namespace std;

inline int read()
{
    int ans=0;
    char last= ,ch=getchar();
    while(ch<0||ch>9) last=ch,ch=getchar();
    while(ch>=0&&ch<=9) ans=ans*10+ch-0,ch=getchar();
    if(last==-) ans=-ans;
    return ans;
}

const int maxn=1e6+10;
int n,k;
int a[maxn];
struct node
{
    int pos,val;
    node(int a,int b) : pos(a),val(b){}  //构造函数
} ;
deque<node>p,q;

int main()
{
    n=read();k=read();
    for(int i=1;i<=n;i++) 
       a[i]=read();
    
    for(int i=1;i<=n;i++)
    {
        while(!p.empty() &&p.back().val>a[i] ) p.pop_back() ;
        p.push_back(node(i,a[i]));
        while(p.front().pos<=i-k ) p.pop_front() ;
        if(i>=k) printf("%d ",p.front().val );
    }
    printf("\n");
    for(int i=1;i<=n;i++)
    {
        while(!q.empty() &&q.back().val<a[i] ) q.pop_back() ;
        q.push_back(node(i,a[i]));
        while(q.front().pos<=i-k ) q.pop_front() ;
        if(i>=k) printf("%d ",q.front().val );
    }
    return 0;
}

 

then,3倍经验

2.P1440 求m区间内的最小值(这题卡ST)

3.P2032 扫描

 

单调队列

标签:||   deque   滑动窗口   插入   string   例题   http   last   etc   

原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11289002.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!