题目:http://poj.org/problem?id=2823
单调队列,顾名思义,就是队列中的元素是单调的。
单调队列的维护:
以单调递增队列来举例:
1、如果队列的长度一定,先判断队首元素是否在规定范围内,如果超范围则增长队首。
2、每次加入元素时和队尾比较,如果当前元素小于队尾且队列非空,则减小尾指针,队尾元素依次出队,直到满足队列的调性为止
#include<iostream> #include<cstdio> using namespace std; const int maxn=1e6+10; int inc[maxn],Dec[maxn],num[maxn],maxa[maxn],mina[maxn]; int pre1,last1,pre2,last2,max_len,min_len; int n,k; void inc_push(int i) { while(pre1<=last1&&num[inc[last1]]<num[i]) --last1; inc[++last1]=i;//入队 if(i>=k-1) { if(inc[pre1]<=i-k) pre1++; maxa[max_len]=num[inc[pre1]]; max_len++; } } void dec_push(int i) { while(pre2<=last2&&num[Dec[last2]]>num[i]) --last2; Dec[++last2]=i;//入队 if(i>=k-1) { if(Dec[pre2]<=i-k) pre2++; mina[min_len]=num[Dec[pre2]]; min_len++; } } int main() { scanf("%d%d",&n,&k); pre1=pre2=0; last1=last2=-1; max_len=min_len=0; for(int i=0;i<n;i++) { scanf("%d",&num[i]); inc_push(i); dec_push(i); } for(int i=0;i<min_len-1;i++) printf("%d ",mina[i]); printf("%d\n",mina[max_len-1]); for(int i=0;i<max_len-1;i++) printf("%d ",maxa[i]); printf("%d\n",maxa[max_len-1]); }