poj2823 单调队列初步

什么是单调队列:头元素一直是队列当中的最大值,队列中的值按照递减顺序排列,可以从末尾插入一个元素,或从两段删除元素

1.插入元素,为了保证队列的单调性(这里假设为递减性),在插入元素v时要将对位的元素和v比较,如果队尾的元素不大于v,删掉,直到队尾元素大于v,再将v插入队尾

2.删除元素,队尾的删除如上所述,队首的删除是一直到队首的元素不存在集合时,再将其删除

模板题poj2823

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define maxn 1000005

using namespace std;

int l,r,n,k,a[maxn],q[maxn];//队列里保存元素的下标 

void workmin(){
    int l=1,r=0,i=0;
    for(;i<k-1;i++){//将前k个插入队尾 
        while(l<=r && a[q[r]]>a[i])r--;
        q[++r]=i;
    }
    for(;i<n;i++){
        if(q[l]<=i-k)l++;//删掉首元素 
        while(l<=r&&a[q[r]]>a[i]) r--; 
        q[++r]=i;//新元素入队尾 
        printf("%d ",a[q[l]]); 
    } 
    puts("");
}
void workmax(){
    int l=1,r=0,i=0;
    for(;i<k-1;i++){
        while(l<=r&&a[q[r]]<=a[i]) r--;
        q[++r]=i;
    }
    for(;i<n;i++){
        if(q[l]==i-k) l++;
        while(l<=r&&a[q[r]]<=a[i]) r--;
        q[++r]=i;
        printf("%d ",a[q[l]]); 
    }
    puts("");
}
int main(){
    while(scanf("%d%d",&n,&k)==2){
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        workmin();
        workmax();
    }
}
原文地址:https://www.cnblogs.com/zsben991126/p/10139353.html