單調佇列 單調棧專題訓練(不斷更新中 )

2021-08-21 22:39:29 字數 2643 閱讀 1210

練這個專題的原因是被多校賽第三場 problem a. ascending rating 虐了, 看別人部落格發現只有一句解釋:單調佇列的應用 。

這才決定要把單調佇列單調棧摸熟(感謝多校賽虐我千百遍)

給出下標為1 -- n 的陣列 ,從左到右掃(也可以從右向左), 對於當前元素i , 從隊尾不斷地把小於a[i]的出隊(規則自己定)

維護乙個從隊頭到隊尾遞減的佇列。多用於維護區間內最大值, 或者區間內遞增序列包含的元素個數。

給1-n陣列,每次移動長度m的視窗,求視窗第乙個元素 到 視窗內最大元素之間遞增序列個數, 和最大元素的值(具體題意不是這樣的 ,只不過求得上訴資料再處理一下就得到答案了)

本題考慮的是對於 i 而言,[i,i+m-1]區間對 i位置 的影響, 因此此題從右往左掃。滿足區間長度為m 後才開始計算值

維護乙個長度為m的嚴格遞減單調佇列, 佇列裡的內容就是當前元素a[i] 向後掃的 嚴格大於a[i]的元素。且隊首元素就是區間m內的最大值

#include #include #include #include #include #include using namespace std;

const int maxn = 1e7+5;

typedef long long ll;

ll a[maxn], qq[maxn];

int main()

ll tail = 0,head = 1; // head 隊頭 tail隊尾,因為是 ++tail = i 所以tail置0

ll ansa = 0,ansb = 0;

for(ll i=n;i;i--)

}printf("%lld %lld\n",ansa,ansb);

}return 0;

}

**

問題描述

地上從左到右豎立著 n 塊木板,從 1 到 n 依次編號,如下圖所示。我們知道每塊木板的高度,在第 n 塊木板右側豎立著一塊高度無限大的木板,現對每塊木板依次做如下的操作:對於第 i 塊木板,我們從其右側開始倒水,直到水的高度等於第 i 塊木板的高度,倒入的水會淹沒 ai 塊木板(如果木板左右兩側水的高度大於等於木板高度即視為木板被淹沒),求 n 次操作後,所有 ai 的和是多少。如圖上所示,在第 4 塊木板右側倒水,可以淹沒第 5 塊和第 6 塊一共 2 塊木板,a4 = 2。

這是個簡單題,有多種思路, 從左向右掃, 把隊尾元素小於當前元素的彈出隊,1)則剩餘在佇列內的,就是當前能對其的貢獻,ans += tail - head +1 。 2)彈出隊的,當前點對他產生價值,ans += i - qq[tail]-1

#include #include #include #include #include #include using namespace std;

const int maxn = 1e7+5;

typedef long long ll;

int a[maxn], qq[maxn];

int main()

printf("%d\n",ans);

}return 0;

}

經過幾個月辛勤的工作,fj決定讓奶牛放假。假期可以在1…n天內任意選擇一段(需要連續),每一天都有乙個享受指數w。但是奶牛的要求非常苛刻,假期不能短於p天,否則奶牛不能得到足夠的休息;假期也不能超過q天,否則奶牛會玩的膩煩。fj想知道奶牛們能獲得的最大享受指數。

input

第一行:n,p,q.

第二行:n個數字,中間用乙個空格隔開,每個數都在longint範圍內。

output

乙個整數,奶牛們能獲得的最大享受指數。

sample input

5 2 4

-9 -4 -3 8 -6

sample output

data constraint

50% 1≤n≤10000

100% 1≤n≤100000

1<=p<=q<=n

求區間和,那麼就用字首和思想 ,令sum【r】 = sun[r-1]+a[r] ,那麼區間[l , r]的和就等於 sum[r] - sum[l - 1] 。我們令r固定,l的取值範圍是 r-q+1 <= l <= r-p+1 ,則狀態轉移方程為 dp[r] = dp [j] + a[r] ( r-q <= l <= r-p max(dp[j]) )使用單調佇列維護區間範圍 [ r-q , r-p] 內的sum[j]陣列最小值。

#include #include using namespace std;

const int maxn = 10050;

const int inf = 0x3f3f3f3f;

int dp[maxn], a[maxn], qq[maxn];

int main()

int head = 1, tail = 0;

int ans = -inf;

for(int i=p; i<=n; i++)

qq[++top] = i;

}printf("%d\n",ans);

}return 0;

}

單調佇列,棧專題

a題 hdu 1506 題目大意 給你n個點,每乙個點代表當前座標下的矩形的高度,然後問你最大的矩形面積。具體思路 我們可以用乙個棧維護最大值,這個棧內的元素都是保持單調的,如果當前輸入的數比棧頂元素小的話,這個時候我們先算一波棧裡面的最大值,判斷停止的時候是當棧頂元素比當前輸入的元素小的時候停就可...

單調佇列 單調棧

參考文章 單調佇列 poj 2823 給定乙個數列,從左至右輸出每個長度為m的數列段內的最小數和最大數。數列長度 n 106 m n n 106,m n n 106 m n 直接暴力求解複雜度在0 mn 可以考慮維護區間最值,單調佇列則是維護區間佇列的強大 單調佇列的定義 單調佇列實現的大致過程 1...

專題 單調佇列

單調佇列就是佇列中元素滿足單調性 入隊 從隊尾入隊,在入隊的時候刪掉隊尾比當前入隊的元素大 或小 的元素 出隊 出隊是直接把隊頭元素取出 poj2823 sliding window 滑動視窗 給定乙個長為n陣列以及乙個長為k的滑動視窗,視窗每個時刻向後移動一位,求出每個時刻視窗中數字的最大值和最小...