单调队列
一、单调队列
1.定义
单调队列就是队内元素保持一定单调性的队列,及从队首到队尾单调递增(单调递增队列)或递减(单调递减队列);
2.性质
- 满足队尾到队头入队顺序从早到晚;
- 队列中元素的大小从队首到队尾必须是单调递(增,减,自定义);
二、实现
1. 对于单调递增:
思路:
使用双端队列模拟,使用结构体存储数字的入队时间与数值,如果队列不为空且当前入队的元素与当前在队首的元素入队时间差小于队列长度,则将队首元素出队,如果队列不为空且入队元素小于队首元素值,则说明入队会破坏队的单调性,因此需要将比入队元素大的元素全部出队,处理完后,将当前入队元素入队;
代码:
struct num {
int i, x;
};
deque < num > q;
void push (int x) {
if (!q.empty() && q.front().i + k - 1 < i) q.pop_front();
while (!q.empty() && q.back().x > a[i]) q.pop_back();
q.push_back( num ( { i, a[i] } ) );
}
2.对于单调递减:
思路:
使用双端队列模拟,使用结构体存储数字的入队时间与数值,如果队列不为空且当前入队的元素与当前在队首的元素入队时间差小于队列长度,则将队首元素出队,如果队列不为空且入队元素大于队首元素值,则说明入队会破坏队的单调性,因此需要将比入队元素小的元素全部出队,处理完后,将当前入队元素入队;
代码:
struct num {
int i, x;
};
deque < num > q;
void push (int x) {
if (!q.empty() && q.front().i + k - 1 < i) q.pop_front();
while (!q.empty() && q.back().x < a[i]) q.pop_back();
q.push_back( num ( { i, a[i] } ) );
}