1. 程式人生 > 其它 >洛谷P1886 滑動視窗 /【模板】單調佇列 /Poj 2823 Sliding Windows

洛谷P1886 滑動視窗 /【模板】單調佇列 /Poj 2823 Sliding Windows

【題目】

這裡

【審題】

略。

【分析】

1.問:暴力怎麼寫?

  答:列舉區間起點,直接模擬。時間複雜度O(nk).

2.問:為什麼用單調佇列更優?

  答:(1)單調佇列中的元素或相關資料具有單調性,可用於求最值。

    (2)單調佇列中的元素下標一定遞增,符合視窗滑動的特點。

3.問:還可以用什麼來實現?

  答:線段樹、st表(都為nlogn),但資料範圍1e6,必定會卡。

【做題時遇到的問題】

如圖,第一種寫法沒有先判重就呼叫了q.back(),導致RE。

在csp-s 2021 的時候想到過這個問題,但是沒有今天這麼透徹。當時的做法是如果優先佇列為空,則單獨設一個值為0的變數來比較。

【程式碼實現】

#include<bits/stdc++.h>
using namespace std;
deque<int> q;
int n,m,a[1000005];
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n;i++){
        
        // while(a[i]<a[q.back()]&&!q.empty()){
        
// q.pop_back(); // } while(!q.empty()&&a[i]<a[q.back()]) q.pop_back(); q.push_back(i); if(i>=m) { while(i-q.front()>=m&&!q.empty()) { q.pop_front(); } printf("
%d ",a[q.front()]); } } printf("\n"); while(!q.empty()) q.pop_front(); for(int i=1;i<=n;i++){ while(!q.empty()&&a[i]>a[q.back()]) q.pop_back(); q.push_back(i); if(i>=m) { while(i-q.front()>=m&&!q.empty()) { q.pop_front(); } printf("%d ",a[q.front()]); } } return 0; }