2017 7 7普及 終極數

2021-08-15 10:47:01 字數 1531 閱讀 5907

題目大意

解題思路

**題目描述

給定乙個長度為n的序列a,試求出對於序列a的每乙個字首的終極數x,使得

最小,試求出終極數t(如若有多個終極數t,只需輸出最小的那個)

第一行乙個整數n,第二行n個整數,中間用空格隔開

輸出一行乙個整數,即表示終極數t

由於題目較為苦澀難懂,【先看一下–>解題思路】,其實就是求出多個中位數後,再求多個中位數的中位數…

對於 20%的資料:直接暴力

對於 40%的資料:顯然的,對於乙個序列的終極數,肯定就是這個序列的中位數,那麼可以用快排,做到 o( )

對於 100%的資料:找中位數,可以用堆,

我們維護兩個堆,乙個大根堆,乙個小根堆,當前每次加入乙個數,必須保證小根堆的個數大於等於大根堆的個數,亦即——第一次加入數的時候肯定是放到最小堆。

其次,我們還需保證小根堆裡的每個值必須大於等於大根堆當中的最大值。

並且,我們當前大根堆的個數如果已經小於小根堆的話,則要把下乙個數加到大根堆裡,反之亦然。

而當我們加入乙個數時,會有兩種特殊情況:

設加入的數為 x,如果欲加入到大根堆裡時,x 大於小根堆的堆頂,則進行 temp1 操作。

反之————— 如果欲加入到小根堆裡時,x 小於大根堆的堆頂,則進行 temp2 操作。

temp1:把 x 放到小根堆中,並且把小根堆的堆頂放到大根堆當中,並維護兩堆性質。

temp2:把 x 放到大根堆中,並且把大根堆的堆頂放到小根堆當中,並維護兩堆性質。

我們求的是每一次小根堆的堆頂…

#include

#include

using

namespace std;

int n,u,num,nuu,a[

1000001

],b[

1000001

],d[

1000001];

void

upa(

int x)

//因為有兩個根堆,方便操作,定義兩個up和down

void

downa

(int x)

//小跟堆

}void

upb(

int x)

void

downb

(int x)

//大根堆

}int

main()

else

}else

//否則放入大根堆裡

else

} d[i]

=a[1];

//取中位數

}sort

(d+1

,d+n+1)

;printf

("%d"

,d[n/2]

);//取多個中位數中的中位數

return0;

}

DP 2017 7 7普及 和諧數

題目描述 給定乙個長度為n nn的序列a aa,對於每乙個數都可選或不選,把選出的數有序組成乙個新的序列b bb,使b bb序列的 和諧數 最大。乙個序列的和諧數如下定義 對於位置i ii,如果第奇數次選的則加上b ib i bi 偶數次選的則減去b ib i bi 注意 新的序列b bb必須是從左...

數學 2017 7 7普及 串

題目描述 給定乙個0 1串,請找到乙個盡可能長的子串,其中包含的0與1的個數相等。輸入 乙個字串,只包含01,長度不超過1000000。輸出 一行乙個整數,最長的0與1的個數相等的子串的長度。樣例輸入 1011 樣例輸出 2資料範圍限制 30 的資料 串的長度 20 思路題面看著這麼舒服,結果難的跟...

jzoj P2152 2017 7 7普及 終極數

題目大意 給定乙個長度為n的序列a,試求出對於序列a的每乙個字首的終極數x,使得 最小,試求出終極數t 如若有多個終極數t,只需輸出最小的那個 題解 雖然看似很迷,其實就是每次插入後的中位數中排序後的中位數 我們維護兩個堆來處理,乙個大根堆,乙個小根堆,當前每次加入乙個數,必須保證 小根堆的個數大於...