POJ2823 classic monotonic queue

POJ2823 Monotonic queue

Problem address poj.org/problem?id=2823

Video explanation address https://www.bilibili.com/video/av23189029?from=search&seid=7739016115400904464

Given an array of length N, a sliding window of length K moves from the far left to the far right. You can only see the K number of windows, each time the window moves one bit to the right. Your task is to find the maximum and minimum values ​​of the window at each position.

A monotonic queue has the property that all elements in the queue either increase or decrease monotonically, so the minimum (maximum) value each time must be at the head of the queue.

In the process of program implementation, the first k elements are added to the team, and then a[k+1...n] is added to the end of the team each time, and the following operations are simultaneously performed in the inserted elements:

1. Pop out all values ​​greater than a[i] at the end of the queue

2. Insert a[i] to the end of the line

3. Determine whether the position of the head element of the team exceeds ik

In terms of finding the maximum value of each interval, an element with a larger value and a lower position will be more useful. This number is more likely to be the maximum value of the interval, so it is necessary to kick out the number smaller than the newly added number queue.

Specifically, two deques can be established to handle the interval maximum and interval minimum respectively.

AC code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<cstdlib>
using namespace std;
#define scan(n) scanf("%d",&n)
#define ll long long

struct node
{
    
    
    int pos,val;
}a;
deque<node>maxq,minq;
int ma[1000005],mi[1000005];
int main()
{
    
    
    int n,k,x,i;
    scan(n);
    scan(k);
    while(!maxq.empty())
        maxq.pop_back();
    while(!minq.empty())
        minq.pop_back();
    for(i=1;i<k;i++)
    {
    
    
        scanf("%d",&x);
        while(!maxq.empty()&&maxq.back().val<=x)
            maxq.pop_back();
        while(!minq.empty()&&minq.back().val>=x)
            minq.pop_back();
        a.pos=i,a.val=x;
        maxq.push_back(a);
        minq.push_back(a);
    }
    for(i=k;i<=n;i++)
    {
    
    
        while(!maxq.empty()&&maxq.front().pos<i-k+1)//先踢掉超出范围的
            maxq.pop_front();
        while(!minq.empty()&&minq.front().pos<i-k+1)
            minq.pop_front();
        scanf("%d",&x);
        while(!maxq.empty()&&maxq.back().val<=x)//再踢掉非最优解
            maxq.pop_back();
        while(!minq.empty()&&minq.back().val>=x)
            minq.pop_back();
        a.pos=i,a.val=x;
        maxq.push_back(a);
        minq.push_back(a);
        ma[i]=maxq.front().val;
        mi[i]=minq.front().val;
    }
    printf("%d",mi[k]);
    for(i=k+1;i<=n;i++)
        printf(" %d",mi[i]);
    printf("\n");

    printf("%d",ma[k]);
    for(i=k+1;i<=n;i++)
        printf(" %d",ma[i]);
    printf("\n");

    return 0;
}

Guess you like

Origin blog.csdn.net/qq_40534166/article/details/97631726