POJ2823-Sliding Window

Given two numbers n and k, next give a sequence of n numbers. Each time a window of length k is maintained, and the maximum and minimum values ​​of this range are found. Move one unit to the right at a time.

Consider how to get the maximum value of an interval and add a number each time. If this number is smaller than the current maximum value, how can it be maintained without maintenance. If it is larger than the current value, then it will be considered. But when the maximum value is on the far left, it can't be in this interval next time. So what we're maintaining is the leftmost position where a value can exist. That is, the lifetime of position i is at most i+k, but if a number larger than it appears in the middle, then there is no need to maintain this number, and it can be replaced by the number that appears. Because it is always better than maintaining the current number, both numerically and positionally.

That is to say, we need to maintain a decreasing sequence, which can be implemented with a monotonic queue to achieve O(n) complexity.

The minimum value is the same, the code is as follows:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <algorithm>
using namespace std;

int n,k,v[2333333],q[23333333];
int main() {
    while(~scanf("%d%d",&n,&k)){
        for(int i=1;i<=n;++i)
            scanf("%d",&v[i]);
        
        int l = 1 , r = 1 ;
        q[1]=0;
        v[0]=1e9;
        for(int i=1;i<=n+1;++i){
            while(l<=r&&q[l]+k<i)
                ++l;
            if(i<=k)
                ;
            else printf("%d ",v[q[l]]);
            while(l<=r&&v[q[r]]>=v[i])
                --r;
            q[++r]=i;
        }
        puts("");
        //printf("%d\n",v[q[l]]);
        l=1,r=1;
        q[1]=0;
        v[0]=-1e9;
        for(int i=1;i<=n+1;++i){
            while(l<=r&&q[l]+k<i)
                ++l;
            /*
            for(int j=l;j<=r;++j)
            printf("%d ",v[q[j]]);
            puts("");
            */
            if(i<=k)
                ;
            else 
                printf("%d ",v[q[l]]);
            while(l<=r&&v[q[r]]<=v[i])
                --r;
            q[++r]=i;
        }
        puts("");
        //printf("%d\n",v[q[l]]);
    }
    return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325013001&siteId=291194637