单调队列
滑动窗口,求多段区间的最大最小值
考虑当 [l,r] 变为 [l+1,r+1] 时要做的事
-
第 l 个元素(如果有)不再做贡献了,将他弹出队列
-
将第 r+1 个元素加入。若此时队列顶的元素 x 比 r+1 小,说明 r+1 永远比 x 更优(x 比 r+1 先退役,不会出现一个区间有 x 而没有 r+1 )
-
更新 [l+1,r+1] 的最大值
代码
// 不要学我用双端队列
// 自己手写队列常数小
int k , n , a[maxn];
void workmax(){
deque<int> q;
fo(i,1,k-1){
while(!q.empty() and a[q.back()] < a[i]) q.pop_back();
q.push_back(i);
}
fo(i,k,n){
int st = i-k+1;
while(!q.empty() and q.front() < st) q.pop_front();
while(!q.empty() and a[q.back()] < a[i]) q.pop_back();
q.push_back(i);
printf("%d ",a[q.front()]);
}
puts("");
}