您的位置:首页 > 其它

POJ 2823 Sliding Window 单调队列

2016-08-29 19:56 405 查看
题意很明显,注意用C++提交,不然会超时。

说说我对单调队列的理解吧。

其实就是每次都在队头保留了ans。就是每次你想知道第i个位置的答案,每次取出队头元素就OK了。

然后就是怎么维护了。

例如要求最大值,那么,队头应该是一个最大值的。所以这个队列是单调递减的,每次插入a[i]的时候,维护它单调递减就OK,同时可以把它插入的这个位置后面的值删除了,是没用了。因为a[i]比他们大,而且比他们新。

关键就是这个新了。

应该这些元素不在这个窗口的话,那些就属于废弃元素,废弃元素不能被选择,所以队列有第二个参数。id。保留队头元素在数组a[i]的pos。那么当对头的id == i - k的时候。它就是废弃的了。然后把head++即可。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
int n,k;
const int maxn = 1e6 + 20;
int a[maxn];
struct node {
int val,id;
node () {}
node (int vv,int ii) : val(vv), id(ii) {}
}que[maxn];
int ans_min[maxn];
int ans_max[maxn];
void work ()
{
int lenmin = 0, lenmax = 0;
scanf ("%d%d", &n, &k);
for (int i = 1; i <= n; ++i) {
scanf ("%d", a + i);
}
//    if (k > n) {
//        while (1);
//    }
que[1].val = a[1];
que[1].id = 1;
int head = 1, tail = 1;
for (int i = 2; i <= k; ++i) { //开始预处理
while (tail >= head && a[i] >= que[tail].val) --tail;
++tail;
que[tail].val = a[i];
que[tail].id = i;
}
ans_max[++lenmax] = que[head].val;
for (int i = k + 1; i <= n; ++i) {
while (tail >= head && a[i] >= que[tail].val) --tail;
++tail;
que[tail].val = a[i]; que[tail].id = i;
while (head <= tail && que[head].id == i - k) ++head;
ans_max[++lenmax] = que[head].val;
}

head = tail = 1;
que[tail].val = a[1];
que[tail].id = 1;
for (int i = 2; i <= k; ++i) {
while (tail >= head && a[i] <= que[tail].val) --tail;
++tail;
que[tail].val = a[i];
que[tail].id = i;
}
ans_min[++lenmin] = que[head].val;
for (int i = k + 1; i <= n; ++i) {
while (tail >= head && a[i] <= que[tail].val) --tail;
++tail;
que[tail].val = a[i]; que[tail].id = i;
while (head <= tail && que[head].id == i - k) ++head;
ans_min[++lenmin] = que[head].val; //每次取队头就是ans
}
for (int i = 1; i <= lenmin; ++i) {
printf ("%d ", ans_min[i]);
}
printf ("\n");
for (int i = 1; i <= lenmax; ++i) {
printf ("%d ", ans_max[i]);
}
printf ("\n");
return ;
}

int main()
{
#ifdef local
freopen("data.txt","r",stdin);
#endif
work ();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: