单调队列是指:队列中元素之间的关系具有单调性,而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作。
以单调不减队列为例:队列内的元素(e1,e2,e3...en)存在(e1<=e2<=e3<=...<=en)的关系,所以队首元素e1一定是最小的元素。与优先队列不同的是,当有一个新的元素e入队时,先要将队尾的所有大于e的元素弹出,以保证单调性,再让元素e入队尾。
例如这样一组数(1,3,2,1,5,6),进入单调不减队列的过程如下:
1入队,得到队列(1);
3入队,得到队列(1,3);
2入队,这时,队尾的的元素3>2,将3从队尾弹出,新的队尾元素1<2,不用弹出,将2入队,得到队列(1,2);
1入队,2>1,将2从队尾弹出,得到队列(1,1);
5入队,得到队列(1,1,5);
6入队,得到队列(1,1,5,6);
代码实现
这个代码是实现单调不递减的队列
#include<bits/stdc++.h>
const int N=1e6+10;
using namespace std;
int a[N];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(a,0,sizeof(a));
int i;
deque<int>num;
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
num.push_back(a[1]);
int a1,a2;
for(i=2; i<=n; i++)
{
if(!num.empty())
a1=num.back();
while(1)
{
if(a1<=a[i]||num.empty())
{
num.push_back(a[i]);
break;
}
else if(!num.empty())
{
num.pop_back();
if(!num.empty())
a1=num.back();//3
}
}
}
while(!num.empty())
{
printf("%d ",num.front());
num.pop_front();
}
printf("\n");
}
return 0;
}