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;
}