题意很明显,注意用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