http://poj.org/problem?id=2823
这就要用到单调递减或单调递增队列来实现,它的头元素一直是队列中的最小值或最大值。我们可以从队列的末尾插入一个元素,可以从队列的两端删除元素。
插入元素:
对于单调递减队列:队头放最大值,为了保持队列的递减性,我们在插入元素v的时候,要将队尾元素与v比较,如果队尾<v,则删除队尾元素,然后继续将新的队尾元素与v比较,直到队尾元素>v,这时才将v插入队尾。
删除队首元素:
队尾元素的删除刚刚已经说了,那么队首的元素什么时候删除呢?当队首元素的索引或下标小于i-k+1的时候,说明队首元素已经没用了,因为他已经不在窗里了,所以当队首元素索引或下标<i-k+1时,将队首元素删除。
#include<iostream>
#include<cstdio>
#include<deque>
using namespace std;
const int maxn=1e6+6;
struct node
{
int val,id;
};
int minn[maxn],maxx[maxn],a[maxn];
int main()
{
int n,k,i;
node now;
deque<node>qmin;
deque<node>qmax;
scanf("%d%d",&n,&k);
scanf("%d",&now.val);
now.id=1;
a[1]=now.val;
minn[1]=now.val;
qmin.push_back(now);
for(i=2;i<=n;i++)
{
scanf("%d",&a[i]);
now.val=a[i];
now.id=i;
while(!qmin.empty()&&qmin.back().val>a[i])
qmin.pop_back();
qmin.push_back(now);
if(!qmin.empty()&&qmin.front().id<i-k+1)
qmin.pop_front();
minn[i]=qmin.front().val;
}
maxx[1]=a[1];
now.val=a[1];
now.id=1;
qmax.push_back(now);
for(i=2;i<=n;i++)
{
now.val=a[i];
now.id=i;
while(!qmax.empty()&&qmax.back().val<a[i])
qmax.pop_back();
qmax.push_back(now);
if(!qmax.empty()&&qmax.front().id<i-k+1)
qmax.pop_front();
maxx[i]=qmax.front().val;
}
for(i=k;i<n;i++)
printf("%d ",minn[i]);
printf("%d\n",minn[n]);
for(i=k;i<n;i++)
printf("%d ",maxx[i]);
printf("%d\n",maxx[n]);
}