单调队列就是维护一个顺序队列,或增或减,用STL的数据结构的话需要用deque(双向队列),被queue坑了一下午。
单调队列的思想大概就是一个已有递增队列(求最小),加入一个数a时,需要将队列最后一个数与a比较,若大于等于a,则pop掉,这个时候就是queue不能解决的了,需要pop_back(),直到空队列或者队列末尾数字小于a,将a push进队列。
下面是Sliding Window的代码实现,效率并不高(逃走 。
原题链接:http://poj.org/problem?id=2823
#include<cstdio>
#include<deque>
using namespace std;
const int M = 1000005;
int min_[M],max_[M];
struct node{
int step,num;
}number;
deque<node>q1,q2;
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;i<n;++i)
{
scanf("%d",&number.num);
number.step = i;
if(i != 0) //滑窗范围
{
if(i - q2.front().step >= k) q2.pop_front();
if(i - q1.front().step >= k) q1.pop_front();
}
while(!q1.empty()) //维护递减
{
if(q1.back().num < number.num) break;
q1.pop_back();
}
q1.push_back(number);
while(!q2.empty()) //维护递增
{
if(q2.back().num > number.num) break;
q2.pop_back();
}
q2.push_back(number);
min_[i] = q1.front().num;
max_[i] = q2.front().num;
}
for(int i=k-1;i<n;++i)
printf("%d ",min_[i]);
printf("\n");
for(int i=k-1;i<n;++i)
printf("%d ",max_[i]);
puts("");
return 0;
}