P3834 模板 可持久化線段樹 1(主席樹)

2021-09-25 18:38:56 字數 1124 閱讀 3738

主席樹 菜雞看了乙個晚上的時間才懂。 感覺網上的部落格大都大亂。我也是找到了幾遍好一點的看了一下。

參考部落格:

參考部落格:

首先,會主席樹的前提是會線段樹。

還有,我們一般在用線段樹的時候,下標位置大都是採用了i * 2 和i* 2 + 1來作為i號的左右孩子。但是,在主席樹中,我們不可以把這種思想帶過來。因為主席樹的是又多個線段樹構成,那麼也就是說每個節點的左右孩子都是會被重複利用的。我們如果用i2 和i 2 + 1來考慮,那就gg了。

所以,我們要先了解線段樹的動態開點。這個其實也很簡單。

他把左右孩子的結點分別用l陣列和r陣列來進行儲存。如果需要增加乙個結點,那麼就直接把下標值加1了。

同時,主席樹是由多顆線段樹組成的,至於為啥這樣,還請看我安利的第一遍部落格,有詳細**。

具體結合**講解:

#include"stdio.h"

#include"string.h"

#include"algorithm"

using namespace std;

int n,m;

//t陣列儲存的是每顆線段樹的根結點 sum陣列儲存的是以每個結點為根的樹,裡面數字的數量

int t[200010],l[20 * 200010],r[20 * 200010],sum[20 * 200010],top;

int a[200010],b[200010];

void build_tree(int &root,int l,int r)

}void update(int &root,int root1,int l,int r,int x)

int query(int u,int v,int l,int r,int x)

else

return query(r[u],r[v],mid + 1,r,x - num);

}int main()

sort(b + 1,b + 1 + n);

int m = unique(b + 1,b + 1 + n) - b - 1;

build_tree(t[0],1,m);

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

while(m --)

}

P3834 模板 可持久化線段樹 1(主席樹)

這是個非常經典的主席樹入門題 靜態區間第k小 資料已經過加強,請使用主席樹。同時請注意常數優化 如題,給定n個整數構成的序列,將對於指定的閉區間查詢其區間內的第k小值。第一行包含兩個正整數n m,分別表示序列的長度和查詢的個數。第二行包含n個整數,表示這個序列各項的數字。接下來m行每行包含三個整數l...

P3834 模板 可持久化線段樹 1(主席樹)

傳送門 板子,大佬的題解寫的真好 ps 看了看attack大佬的板子 跑的飛快 然後抄了抄 慢的要命 評測機玄學問題?真不知道大佬常數怎麼寫的 更神仙的是大佬居然都不先建樹直接加點 怎麼過的orz 1 luogu judger enable o22 minamoto 3 include4 defin...

P3834 模板 可持久化線段樹 1(主席樹)

這是個非常經典的主席樹入門題 靜態區間第k小 資料已經過加強,請使用主席樹。同時請注意常數優化 如題,給定n個正整數構成的序列,將對於指定的閉區間查詢其區間內的第k小值。輸入格式 第一行包含兩個正整數n m,分別表示序列的長度和查詢的個數。第二行包含n個正整數,表示這個序列各項的數字。接下來m行每行...