noi2010 超級鋼琴 堆 RMQ

2021-07-03 17:27:16 字數 1901 閱讀 4680

【問題描述】

小z是乙個小有名氣的鋼琴家,最近c博士送給了小z一架超級鋼琴,小z希望能夠用這架鋼琴創作出世界上最美妙的**。

這架超級鋼琴可以彈奏出n個音符,編號為1至n。第i個音符的美妙度為ai,其中ai可正可負。

乙個「超級和弦」由若干個編號連續的音符組成,包含的音符個數不少於l且不多於r。我們定義超級和弦的美妙度為其包含的所有音符的美妙度之和。兩個超級和弦被認為是相同的,當且僅當這兩個超級和弦所包含的音符集合是相同的。

小z決定創作一首由k個超級和弦組成的樂曲,為了使得樂曲更加動聽,小z要求該樂曲由k個不同的超級和弦組成。我們定義一首樂曲的美妙度為其所包含的所有超級和弦的美妙度之和。小z想知道他能夠創作出來的樂曲美妙度最大值是多少。

【輸入格式】

輸入檔名為piano.in。

輸入檔案第一行包含四個正整數n, k, l, r。其中n為音符的個數,k為樂曲所包含的超級和弦個數,l和r分別是超級和弦所包含音符個數的下限和上限。

接下來n行,每行包含乙個整數ai,表示按編號從小到大每個音符的美妙度。

【輸出格式】

輸出檔案為piano.out。

輸出檔案只有乙個整數,表示樂曲美妙度的最大值。

【樣例輸入】

4 3 2 332

-68【樣例輸出】11

【樣例說明】

共有5種不同的超級和弦:

音符1 ~ 2,美妙度為3 + 2 = 5

音符2 ~ 3,美妙度為2 + (-6) = -4

音符3 ~ 4,美妙度為(-6) + 8 = 2

音符1 ~ 3,美妙度為3 + 2 + (-6) = -1

音符2 ~ 4,美妙度為2 + (-6) + 8 = 4

最優方案為:樂曲由和弦1,和弦3,和弦5組成,美妙度為5 + 2 + 4 = 11。

【執行時限】

2秒。【執行空限】

512m。

【資料規模和約定】

總共10個測試點,資料範圍滿足:

所有資料滿足:-1000 ≤ ai ≤ 1000,1 ≤ l ≤ r ≤ n且保證一定存在滿足要求的樂曲。

題解:定義乙個結構體(h,l,r,max,maxp)表示合法的序列(已h為左端點,右端點在l和r之間,其中連續子串行的最大值為max,最大連續子串行的右端點在maxp)。用乙個大根堆按區間最大值去維護這些結構體。初始時將每個點所能產生的最大序列入堆,每次從堆中取出最大值,累加到答案裡。然後把區間裂解成l—maxp-1,maxp+1—r兩個區間,分別求出最大值入堆,這樣迴圈k此即可。(求最大值時先預處理出字首和,跑一遍st即可,即最大值=合法區間內的最大字首和-左端點的字首和)

#include#include#include#includeusing namespace std;

struct use;

bool operator

while(ch>='0'&&ch<='9')

return x*f;

}inline void pretreatment()

else break;

}inline use query(int hh,int ll,int rr)

for (int i=1;i<=k;i++)

if (a.maxp+1<=a.r)

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

}

NOI2010 超級鋼琴

傳送門 這個題有趣。巧妙地利用st表和堆 首先最暴力的我就不說了 第二個暴力就是主席樹 堆,預計得分70 80,時間o klog 2n std是用堆儲存可能的區間,然後用st表查詢區間最小值 因為其實如果知道區間右端點,再處理個字首和s 那麼就只要查詢區間最小值就可以了,可以st表o 1 做 inc...

NOI2010 超級鋼琴

求出字首和 對於每個結尾i,設現在取的區間是 j 1,i 則i r j i l,取出該區間sum j 的最小值,將sum i sum j 放入堆中 建立乙個大根堆,每次取出堆頂元素,將排名k 1,將sum i 區間第k小值放入堆中 求區間第k小可以用主席樹 直到取滿k次為止 include incl...

NOI2010 超級鋼琴

和有一道區間前k大異或很像。先求字首和,然後就變成右端點固定,取左端點的第k小問題,主席樹維護即可。並用堆維護前k個。ac pragma gcc optimize ofast funroll all loops include define int long long using namespace...