洛谷題單指南-常見最佳化技巧-P1886 滑動視窗 /【模板】單調佇列

五月江城發表於2024-09-09

原題連結: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]] << " ";
    }
}

相關文章