單調佇列 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