RMQ 超級鋼琴

2021-06-05 11:20:20 字數 2290 閱讀 7808

超級鋼琴:

超級鋼琴

【問題描述】

小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. 音符 1 ~ 2,美妙度為 3 + 2 = 5

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

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

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

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

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

【執行時限】

2秒。【執行空限】

512m。

【資料規模和約定】

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

題目大意:

取前k個最大的連續區間和,區間長度在[l,r]之間。

使用rmq的st演算法和堆來實現。

因此,當左邊界固定的時候,要求乙個最大的區間和,就在所有右邊界的可能取值中,找乙個字首和最大的。

這時候,rmq就隆重登場了。以前沒有想過,最大區間和和區間最大值可以這樣轉換呀。。其實很簡單的,只是我轉不過彎。

因此我們需要找到對於所有的i,[i,i+l-1]、[i,i+l]……[i,i+r-1]這些區間之中的最大值,總共有n個。

我們用堆來維護比較好。

注意:當從堆中取出乙個最大的時候,可能對於這個i,[i,i+l-1]、[i,i+l]……[i,i+r-1]這些區間之中的次大值,會比對於其他i的最大值更大。

因此我們需要將這些區間重新放回去,除開[i,i+pos-1],假設i+pos-1是原來的最大值。實現方法參見wjj的部落格whjpji。

這道題確實很巧妙呀我覺得。

兩個版本最後兩個點都超時,想不出辦法來了。

手寫堆版:

#include #include //#include #define max(a,b) (a>b?a:b)

#define min(a,b) (an2.maxsum;

} node(){}

};node heap[1000010];

int size = 0;

inline int rmq(int l,int r)

}inline void pop()

inline void adjust_up(int l)

}inline void push(node l)

inline int getint()

do res = (res << 1) + (res << 3) + tmp - '0';

while (isdigit(tmp = getchar()));

return sgn ? res : -res;

}int main()

} for (int i=1;i+l-1

#include #include #include #define max(a,b) (a>b?a:b)

#define min(a,b) (aheap;

inline long lg2(ll a)

long rmq(long l,long r)

} for (long i=1;i+l-1

noi2010 超級鋼琴 堆 RMQ

問題描述 小z是乙個小有名氣的鋼琴家,最近c博士送給了小z一架超級鋼琴,小z希望能夠用這架鋼琴創作出世界上最美妙的 這架超級鋼琴可以彈奏出n個音符,編號為1至n。第i個音符的美妙度為ai,其中ai可正可負。乙個 超級和弦 由若干個編號連續的音符組成,包含的音符個數不少於l且不多於r。我們定義超級和弦...

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...