原題連結:https://www.luogu.com.cn/problem/P1886
題意解讀:單調佇列模版題。
解題思路:
採用雙端佇列維護單調的序列,單調佇列三部曲:
1、去頭,當視窗內元素個數超過k,隊頭出隊
2、去尾,當要加入的元素會破壞單調性,隊尾出隊
3、入隊,將元素的下標存入佇列
每一次入隊後,隊頭元素即為視窗最值。
100分程式碼:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000005;
int n, k;
int a[N];
int q[N], head , tail; //手寫雙端佇列
int main()
{
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i];
head = 0, tail = -1; //初始化隊頭,隊尾指標
for(int i = 1; i <= n; i++)
{
//去頭
while(head <= tail && i - q[head] + 1 > k) head++;
//去尾
while(head <= tail && a[i] < a[q[tail]]) tail--;
//入隊
q[++tail] = i;
if(i >= k) cout << a[q[head]] << " ";
}
cout << endl;
head = 0, tail = -1; //初始化隊頭,隊尾指標
for(int i = 1; i <= n; i++)
{
//去頭
while(head <= tail && i - q[head] + 1 > k) head++;
//去尾
while(head <= tail && a[i] > a[q[tail]]) tail--;
//入隊
q[++tail] = i;
if(i >= k) cout << a[q[head]] << " ";
}
}