第三章:单调队列
1.P1886 滑动窗口 /【模板】单调队列 - 洛谷
#include<iostream>
#include<deque>
using namespace std;
int n, m;
const int N = 1e6 + 10;
int a[N];
int main()
{
cin >> n >> m;
deque<int> q;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
//单调递增 - 最小值 - 存下标
for (int i = 1; i <= n; i++)
{
int t = a[i];
while (q.size() && a[q.back()] >= t)q.pop_back();//小的放前面,t小就放前面,pop掉
q.push_back(i);
if (q.back() - q.front() + 1 > m)
{
q.pop_front();
}
if (i >= m)cout << a[q.front()]<<" ";
}
//单调递减 - 最大值 - 存下标
q.clear();
cout << endl;
for (int i = 1; i <= n; i++)
{
int t = a[i];
while (q.size() && a[q.back()] <= t)q.pop_back();
q.push_back(i);
if (q.back() - q.front() + 1 > m)
{
q.pop_front();
}
if (i >= m)
cout << a[q.front()] << " ";
}
return 0;
}
以求最大值为例子:
如果当前a[i] >= a[q.back()],那么把比a[i]小的全部都出队列,然后推进去
如果 < 那就推进队尾
根据队头和队尾的下标判断是否超出m;
超了,出队头
打印队头为最大值
2.P2251 质量检测 - 洛谷
#include<iostream>
#include<deque>
using namespace std;
int n, m;
const int N = 1e6 + 10;
int a[N];
int main()
{
deque<int> q;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
while (q.size() && a[q.back()] >= a[i])q.pop_back();
q.push_back(i);
if (q.back() - q.front() + 1 > m)q.pop_front();
if (i >= m)cout << a[q.front()]<<endl;
}
return 0;
}