1. 程式人生 > >單調佇列 poj2823 Sliding Window

單調佇列 poj2823 Sliding Window

題意:有n個數字,有個寬度為k的視窗,從最左邊向右邊移動,每次都框住k個數字,依次輸出這些框中的最大值和最小值

思路:運用單調佇列維護。一般deque我們都手動模擬,因為一般單調對列對時間複雜度要求都會比較高。

一般令cur=rear=0,rear表示尾指標,其實這個指標是取不到的,也就是說左開由閉。當cur<rear則表示佇列中存在元素

單調佇列數字都是從隊尾進,要求最值的時候一般都是在堆首取。所以說,隊首要求的是最大值還是最小值,也決定了整個佇列是遞增還是遞減。

單調對列一般都是這樣考慮問題的,假如我現在是要維護求最小值的單調佇列

數字一般從隊尾插入t,先要從隊尾開始,將大於t的數字全部刪除,然後才把t加入到隊尾

這時,再考慮隊首開始的是否都符合題意範圍,把不符合的也刪除,也就是cur++移動首指標。

然後再取隊首元素,此時就是當前的最小值

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;

const int MX = 1e6 + 5;
const int INF = 0x3f3f3f3f;

int A[MX];
int Q_1[MX], cur_1, tail_1;//Min
int Q_2[MX], cur_2, tail_2;//Max
int MIN[MX], MAX[MX];

int main() {
    int n, k; //FIN;
    while(~scanf("%d%d", &n, &k)) {
        k = min(n, k);
        cur_1 = tail_1 = cur_2 = tail_2 = 0;
        for(int i = 1; i <= n; i++) {
            A[i] = read();
        }

        for(int i = 1; i <= n; i++) {
            while(cur_1 < tail_1 && A[Q_1[tail_1 - 1]] > A[i]) tail_1--; Q_1[tail_1++] = i;
            while(cur_2 < tail_2 && A[Q_2[tail_2 - 1]] < A[i]) tail_2--; Q_2[tail_2++] = i;
            if(i >= k) {
                while(cur_1 < tail_1 && Q_1[cur_1] < i - k + 1) cur_1++;
                while(cur_2 < tail_2 && Q_2[cur_2] < i - k + 1) cur_2++;
                MIN[i - k + 1] = A[Q_1[cur_1]];
                MAX[i - k + 1] = A[Q_2[cur_2]];
            }
        }

        for(int i = 1; i <= n - k + 1; i++) {
            printf("%d%c", MIN[i], i == n - k + 1 ? '\n' : ' ');
        }
        for(int i = 1; i <= n - k + 1; i++) {
            printf("%d%c", MAX[i], i == n - k + 1 ? '\n' : ' ');
        }
    }
    return 0;
}


相關推薦

單調佇列 poj2823 Sliding Window

題意:有n個數字,有個寬度為k的視窗,從最左邊向右邊移動,每次都框住k個數字,依次輸出這些框中的最大值和最小值 思路:運用單調佇列維護。一般deque我們都手動模擬,因為一般單調對列對時間複雜度要求都會比較高。 一般令cur=rear=0,rear表示尾指標,其實這個指標

POJ2823 Sliding Window單調佇列】【線段樹】【ST表】

Sliding Window 題意: 給出一個長度為N的序列,通過一個視窗,可以看到序列中連續的K個元素,視窗從最左邊出發,每次移動一個單位,對於每次移動,輸出當前視窗中的最大值和最小值 單調遞減佇列:從隊頭到隊尾單調遞減的佇列 入隊操作,先把隊尾元素中小於X的元

[POJ2823]Sliding Window 滑動視窗(單調佇列)

題意 剛學單調佇列的時候做過 現在重新做一次 一個很經典的題目   現在有一堆數字共N個數字(N<=10^6),以及一個大小為k的視窗。現在這個從左邊開始向右滑動,每次滑動一個單位,求出每次滑動後窗口中的最大值和最小值。 思路 單調佇列 一個遞增 一個遞減 程式碼

POJ2823——Sliding Window 單調佇列入門

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 40596 Accepted: 11992 Case Time Limit: 5000MS Description

poj2823 Sliding Window (優先佇列)

/* 題意: 有N個數,每次從左到右選取M個數,第一行選取每個區間中的最小值輸出,第二行選取最大值並輸出。 */ # include <stdio.h> # include <string.h> # include <algorithm>

POJ2823-Sliding Window

IT 區間 for urn pac LG div clu can 給定兩個數n和k,接下來給出n個數的數列。每次維護一個長度為k的窗口,求出這個範圍的最大值和最小值。每次向右移動一個單位。 考慮如何得出一個區間的最大值,每次增加一個數,如果這個數比當前的最大值小,如何是可以

[線段樹] poj2823 Sliding Window

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 46075 Accepted: 13317 Case Time Limit: 500

單調佇列 POJ2823

看這個問題:An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array to the

單調隊列 Sliding Window POJ - 2823

queue 循環 bits deque 連續子序列 def ring int ctype 單調隊列在求滑動窗口的時候用 例:給出一個長度為n的序列A,求A中所有長度為m的連續子序列的最大值 解法就是 用一個雙端隊列 始終保持隊列中的元素的個數為m 求最大值就

[POJ2823] [POJ0604月賽] Sliding Window [單調佇列/線段樹]

大家都知道的單調佇列模板題 被卡時間了,難受 poj上G++過不去 只能換C++ #include<cstdio> #include<iostream> #include<algorithm> #include<cs

POJ - 2823 Sliding Window單調佇列優化dp && c++快讀】

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 72718 &nb

POJ-2823-Sliding Window單調佇列

原題連結: http://poj.org/problem?id=2823 An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the ver

2823 Sliding Window單調佇列優化dp && c++快讀】

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 72718 Acc

單調佇列 POJ 2823 Sliding Window

  Sliding Window An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from

【POJ 2823】Sliding Window 【滑動視窗/單調佇列入門

題目大意 輸入一個長度為n(n≤≤106106)的數列,給定一個長度為k的視窗,讓這個視窗在數列上移動,求移動到每個位置視窗中包含數的最大值和最小值。即設序列為A1,A2,…,AnA1,A2,…,AnA1,A2,…,An,設f(i)=minAi−k+1Ai−k+

Sliding Window 單調佇列解決--經典滑動視窗問題--求視窗的最大值最小值

這就要用到單調遞減或單調遞增佇列來實現,它的頭元素一直是佇列中的最小值或最大值。我們可以從佇列的末尾插入一個元素,可以從佇列的兩端刪除元素。 插入元素: 對於單調遞減佇列:隊頭放最大值,為了保持佇列的遞減性,我們在插入元素v的時候,要將隊尾元素與v比較,如果隊尾<

POJ 2823 Sliding Window (單調佇列)

題目連結 Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the v

Sliding Window POJ - 2823 (單調佇列)

題目連結 這道題是一道非常經典的單調佇列題目. 單調佇列是一種單調遞增或單調遞減的佇列結構, 在C++STL中有priority_queue來實現了, 但較為麻煩只能對隊尾進行操作和訪問, 同時考慮到可能存在超時的因素, 所以在平常做題中我們一般都會選擇自己來實現單調佇列. 對於求類似

POJ 2823 Sliding Window單調佇列||線段樹)

題意: 讓你不停的查詢區間長度為k的最小值和最大值 一開始用set模擬,發現常熟太大,T了,然後開始學單調佇列,看了一會兒還是好理解的,所以就寫了,發現G++會T,只能交C++,後來發現 有人線段樹也能過,於是就寫了一發,還真行,只不過就是吧

2823 Sliding Window (單調佇列求解區間最值)

POJ - 2823 Time Limit: 12000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu Descri