hdu2665 主席樹模板題

2022-08-17 21:15:13 字數 1283 閱讀 9511

題目

區間k大值,區間極值很容易想到線段樹,如果k是個位數的話,可以考慮開k個域的線段樹= =,,,,滾~

又稱可持久化線段樹,函式式線段樹

也許是上面兩個字看的太長,同時主席兩字給人一種不明覺厲的感覺,,,so,嘿嘿嘿

關於主席樹的講解可以看這

先離散化,對每個點i,建乙個1~i的線段樹(大小是數字的個數)

記錄該字首序列裡出現的值的次數;記離散後的標記為1~n;

對於區間[x,y]的第k大的值,那麼從root[x-1],root[y]開始,

t=root[y].[1,mid]-root[x-1].[1,mid] ,t表示區間[x,y]內值在[1,mid]的個數

先判斷t是否大於k,如果t大於k,那麼說明在區間[x,y]內存在[1,mid]的數的個數大於k,

也就是第k大的值在[1,mid]中,否則在[mid+1,r]中;

這樣我們依次同時從root[x-1],root[y]往下走

當l==r時 第k大的值就是離散後標記為l的值;

如果每棵線段都建完整的化,n^2肯定會mle,,,bang!!!

我們發現對於字首[1,i]和字首[1,i+1]的線段樹,如果b[i+1]<=mid (b[i+1]表示a[i+1]離散後的標記)

那麼線段樹i和線段樹i+1的左邊是完全相同的,根本不需要在建,直接鏈過去就好;

那麼對於一棵新的線段樹其實我們最多要建的節點數為log(n);nlog(n)的節點數,duangduangduang

存個**吧,,,,以後如果寫熟練了有空寫個去重的離散

//嘿嘿嘿

# include

# include

# include

# define n 100100

using namespace std;

int i,n,m,root[n],a[n],p[n],b[n],cnt;

struct nodet[n*30];

bool cmp(int i,int j)

int query(int

x,int

y,int l,int r,int k)

int main()

sort(p+1,p+n+1,cmp);

for (int i=1;i<=n;i++)b[p[i]]=i;

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

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

}return

0;}

hdu2665(主席樹模板題)

求區間第 k 小。參考這類題目做法挺多的,例如 劃分樹。這裡使用主席樹再寫一發,不得不說主席樹相比而言要好寫的多,比起普通線段樹,主席樹就是復用了線段樹共有的資訊。可持久化資料結構講究的就是復用共有的資訊,可持久化 trie 的思想也是差不多的。includeusing namespace std ...

hdu2665 主席樹(可持久化線段樹)

題意 給定乙個陣列,每次查詢第l到r區間的第k大值 經過這題總算對可持久化線段樹有了些了解,我們開始先建一顆空樹,然後對於每次修改我們只會修改logn個點,我們可以新建logn個來避免每次都新建一顆線段樹導致的爆空間,對於這題來說我們線段樹中維護的是這個區間的點的個數,插入的時候按權值大小插入,對於...

hdu 2665 劃分樹裸題

昨天還覺得劃分樹很難,看了一眼別人的 覺得好長然後覺得很沒法下手!今天早上起床還是很耐心的研讀了大牛的 哈哈,原來也不過如此嗎!線段樹和歸併排序的結合,建議大家以後遇到不會的題一定要有耐心,不然就真的學不會了 include include include include include inclu...