HDU3530 Subsequence 單調佇列

2021-09-26 19:53:27 字數 1109 閱讀 2319

先附上大佬部落格orz:

找數列中最長的子串行,要求最大值減去最小值大於等於m小於等於k。這道題被歸到了單調佇列裡,但真的沒想到要用兩個。。之前做過幾道單調佇列的題,實現原理大概就是維護隊首並在隊尾插入元素,保證佇列的單調性。隊首看題目要求,比如限制區間長度,本題在後邊分析;而隊尾每插入乙個元素就要從後往前去除冗雜狀態。

head和tail為維護區間的左右端點,構造兩個單調佇列:乙個遞增序列up和乙個遞減序列down,它們都以tail為結尾,且隊首元素的下標》head;這兩個序列存的是元素值,所以另外再開兩個陣列記錄元素值對應的下標(其實直接記錄下標也可以)。tail從1到n遍歷,每次都插入up和down佇列末尾。難點在於隊首的維護。可知在當前區間中,最大值是down的隊首元素,最小值是up的隊首元素,若max-min>k則需要令head++(使max減小或min增大);若head超過了up或down的隊首元素下標,更新兩陣列的隊首(其實就是隊首指標++)。直到max-min=m是否滿足,滿足則更新答案。附上ac**如下:

#include#include#include#includeusing namespace std;

const int inf=0x3f3f3f3f;

const int max=100005;

int n,m,k;

int a[max];

//遞增序列

int up[max],id1[max];//記錄數值,下標

int h1,t1;//隊首,隊尾

//遞減序列

int down[max],id2[max];

int h2,t2;

void init()

int main()

if(down[h2]-up[h1]>=m)

ans=max(ans,tail-head+1);//更新結果

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

}return 0;

}

hdu 3530 單調佇列

單調佇列就是佇列中的元素是單調遞增或遞減的。比如把 5 2 3 1 4 入隊 減 增 5 5 5 2 2 5 3 2 3 5 3 1 1 5 4 1 4 這個還是好理解的,但是,我們得會用單調佇列這一特性去解決題目,抽象出題目中有類似的操作。subsequence 題意 給三個數 n,x,y 接下來...

hdu3530 Subsequence 單調佇列

題目 在乙個序列中找乙個最長子串,使得子串的m 極差 k.維護乙個遞減的單調佇列q1 隊首為當前最大 同時維護乙個遞增的單調佇列q2 隊首為當前最小 控制最大減最小 小於等於k 若最大減最小大於等於m,則更新答案。include include include include includeusin...

hdu 3530 Subsequence 單調佇列

題目鏈結 題意 給定陣列,求得最長的區間,使得其中最大值與最小值的差值在給定的範圍內 m,k 思路 維護兩個佇列記錄元素下標,lo 與 hi 具體如何維護之後再講 保證 a lo 單調增,且記當前處理到下標 i 的位置,則 a lo x 即為 lo x 1 1 i 區間中的最小值 保證 a hi 單...