Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 47090 | Accepted: 13602 | |
Case Time Limit: 5000MS |
Description
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 33 3 5 5 6 7
题意:给你一个N个数的序列,并固定连续区间长度为k。现让你依次求出所有长度为k的连续区间里面 的最大值和最小值。
思路:裸RMQ,但使用二维会MLE。由于题目已经固定了区间长度k,也就是说我们只需要使用区间长度为k时的信息。我们可以用一维数组按长度递增来推出区间长度为k值的信息。
预处理数组Amax[i]和Amin[i]之后,它们分别存储的是以A[i]开始的,长度为k的连续区间里面的最大值和最小值。
压缩空间思路点这里:点我
AC代码:
#include <cstdio> #include <cstring> #include <algorithm> #define MAXN 1000000+10 using namespace std; int N, k; int A[MAXN]; int Amax[MAXN]; int Amin[MAXN]; void RMQ_init() { for(int i = 1; i <= N; i++) Amax[i] = Amin[i] = A[i]; for(int j = 1; (1<<j) <= k; j++) { for(int i = 1; i + (1<<j) - 1 <= N; i++) { Amax[i] = max(Amax[i], Amax[i + (1<<(j-1))]); Amin[i] = min(Amin[i], Amin[i + (1<<(j-1))]); } } } int query(int L, int R, int mark) { int len = 0; while(1<<(len+1) <= R-L+1) len++; if(mark == 1) return max(Amax[L], Amax[R-(1<<len)+1]); else return min(Amin[L], Amin[R-(1<<len)+1]); } int main() { while(scanf("%d%d", &N, &k) != EOF) { for(int i = 1; i <= N; i++) scanf("%d", &A[i]); RMQ_init(); for(int i = 1; i <= N-k+1; i++) { if(i > 1) printf(" "); printf("%d", query(i, i+k-1, 2)); } printf("\n"); for(int i = 1; i <= N-k+1; i++) { if(i > 1) printf(" "); printf("%d", query(i, i+k-1, 1)); } printf("\n"); } return 0; }