topic
https://www.luogu.org/problemnew/show/1886
P1886 Sliding window
Title description
There are now a bunch of numbers with N numbers (N<=10^6), and a window of size k. Now this one slides from the left to the right, sliding one unit at a time to find the maximum and minimum values in the window after each sliding.
例如:
The array is [1 3 -1 -3 5 3 6 7], and k = 3.There are two lines of input, the first line is n, k, and the second line is n numbers (
<INT_MAX
).There are two lines of output, the first line is the minimum value of each window sliding, the second line is the maximum value of each window sliding
Input example #1:
8 3
1 3 -1 -3 5 3 6 7Output sample #1:
-1 -3 -3 -3 3 3
3 3 5 5 6 7Description
50% of the data, n<=10^5
100% of the data, n<=10^6
analysis
- Make a monotonic queue and record the id (subscript in the original array) and value of the elements in the queue.
- Find the minimum first:
- Every time a new element A is inserted into the end of the queue, all elements larger than A are popped from the end of the queue, keeping the queue monotonous.
- Then judge whether the id of the element at the head of the team has crossed (less than) the boundary, and will leave the team if it crosses.
- Just output the value of the first element of the line each time.
- The same is true for finding the maximum value.
- Time complexity is On.
program
#include <cstdio>
struct zzk{
int v,id;} q[2000005];
int i,n,k,l,r,A,a[1000005];
int main(){
scanf("%d%d",&n,&k);
for (i=1; i<=n; i++) scanf("%d",&a[i]);
for (l=++r,i=1; i<=n; i++){
A=a[i];
if (i-q[l].id>=k) l++;
while (q[r].v>=A && r>=l) r--;
q[++r]=(zzk){A,i};
if (i>=k) printf("%d ",q[l].v);
}
for (puts(""),l=1,r=0,i=1; i<=n; i++){
A=a[i];
if (i-q[l].id>=k) l++;
while (q[r].v<=A && r>=l) r--;
q[++r]=(zzk){A,i};
if (i>=k) printf("%d ",q[l].v);
}
}
prompt
- This problem can also be done with a line segment tree, but the time complexity is more log, and practice is also possible.
- RMQ can also do it.