单调队列

//单调队列 
//队列元素递增或递减 元素最多进队出队各一次 
//应用:复杂度为o(n^2)的动态规划 可求最大最小值 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int n,m,a[1000001];
struct uio{
    int minum,micnt;
}mi[1000001];
struct oiu{
    int manum,macnt;
}ma[1000001];
void getmin()
{
    int h=1,t=0;
    for(int i=1;i<m;i++)//前(m-1)个先入队 
    {
        while(h<=t&&mi[t].minum>=a[i])
            t--;
        mi[++t].minum=a[i];
        mi[t].micnt=i;
    }
    for(int i=m;i<=n;i++)
    {
        while(h<=t&&mi[t].minum>=a[i])
            t--;
        mi[++t].minum=a[i];
        mi[t].micnt=i;
        while(mi[h].micnt<i-m+1)
            h++;
        cout<<mi[h].minum<<" ";
    } 
    cout<<endl;
}
void getmax()
{
    int h=1,t=0;
    for(int i=1;i<m;i++)//前(m-1)个先入队 
    {
        while(h<=t&&ma[t].manum<=a[i])
            t--;
        ma[++t].manum=a[i];
        ma[t].macnt=i;
    }
    for(int i=m;i<=n;i++)
    {
        while(h<=t&&ma[t].manum<=a[i])
            t--;
        ma[++t].manum=a[i];
        ma[t].macnt=i;
        while(ma[h].macnt<i-m+1)
            h++;
        cout<<ma[h].manum<<" ";
    } 
    cout<<endl;
} 
int main() 
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    getmin();
    getmax();
    return 0;
}
原文地址:https://www.cnblogs.com/water-radish/p/9280583.html