4.由于单调队列是求指定长度区间的最值,所以需要控制区间长度。当插入结束后,需要用队尾元素下标和队首元素下标计算是否在一个区间内。如果不在,队首元素出队(队首指针+1)。重复这个过程直到控制到区间内,一次最大值寻找完毕。最大值出现在队首。
补充:本题输出输出量巨大,需要使用输入输出外挂,并且是能处理负数的。
/* ID: sdj22251 PROG: subset LANG: C++ */ #include <iostream> #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <cmath> #include <ctime> #define LOCA #define MAXN 1005*1005 #define INF 100000000 #define eps 1e-7 using namespace std; int a[MAXN]; int q[MAXN]; int in() { int flag = 1; char ch; int a = 0; while((ch = getchar()) == ' ' || ch == '\n'); if(ch == '-') flag = -1; else a += ch - '0'; while((ch = getchar()) != ' ' && ch != '\n') { a *= 10; a += ch - '0'; } return flag * a; } void out(int a) { if(a < 0) {putchar('-'); a = -a;} if(a >= 10)out(a / 10); putchar(a % 10 + '0'); } int main() { int n, k; scanf("%d%d", &n, &k); for(int i = 1; i <= n; i++) a[i] = in(); int head = 0, tail = 0; q[++tail] = 1; for(int i = 1; i <= n; i++) { while(head <= tail && a[q[tail]] >= a[i]) tail--; q[++tail] = i; while(q[tail] - q[head] + 1 > k) head++; if(i == k) out(a[q[head]]); else if(i > k) { putchar(' '); out(a[q[head]]); } } putchar('\n'); head = 0, tail = 0; q[++tail] = 1; for(int i = 1; i <= n; i++) { while(head <= tail && a[q[tail]] <= a[i]) tail--; q[++tail] = i; while(q[tail] - q[head] + 1 > k) head++; if(i == k) out(a[q[head]]); else if(i > k) { putchar(' '); out(a[q[head]]); } } putchar('\n'); return 0; }