Luogu-1886 (monotonic queue)

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.

例如:
Figure
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 7

Output sample #1:

-1 -3 -3 -3 3 3
3 3 5 5 6 7

Description

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.

Guess you like

Origin blog.csdn.net/jackypigpig/article/details/78483870