NOI 2010 超級鋼琴

2022-05-11 12:17:21 字數 2598 閱讀 9008

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

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

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

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

輸入格式:

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

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

輸出格式:

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

輸入樣例#1:

4 3 2 332

-68

輸出樣例#1:

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。

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

對於乙個點i為左端點,它的右端點j在i+l-1~i+r-1

sum為字首和,sum[j]-sum[i-1]說明sum[j]越大越好

顯然區間中的最大值可能會對答案有影響,但不能就此刪去這一段

因為中間還有次大,第3大....可能會影響答案

假設我們已經取了maxi,那麼次大值也許在i+l-1~maxi-1或maxi+1~i+r-1

也就是說可以刪去i+l-1~i+r-1,填入i+l-1~maxi-1和maxi+1~i+r-1

對於很多個這樣產生的區間,我們用乙個五元組(l,r,maxi,i,maxv)

表示區間左右端點,最大值位置,i為上面的意思(方便子區間將maxv-sum[i-1]),maxv為最大的sum[j]

顯然堆大小不會超過2×k

複雜度為nlogn

1 #include2 #include3 #include4 #include5 #include6 #include7

using

namespace

std;

8struct

node9;

13bool

operator

1417

intk,n,l,r,maxi;

18long

long

maxv;

19long

long

ans;

20int max[500001][21

];21

long

long f[500001][21

];22 priority_queueq;

23long

long

gi()

24 30

long

long x=0;31

while (ch>='

0'&&ch<='9'

)3236return flag*x;37}

38void rmq(int x,int

y)39

46else

4751

//cout<52}53

intmain()

54 62

for (i=1;i<=20;i++)

63for (j=1;j<=n;j++)

64if (j+(1

<1)-1

<=n)

6571

else

7276}77

else

break;78

for (i=1;i<=n-l+1;i++)

79);83}

84while (k--)

85);95}

96if (x.i

97);

101}

102}

103 cout<

104 }

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