模板 可持久化線段樹 主席樹

2022-05-11 12:08:53 字數 2142 閱讀 3785

這是一道非常直白的可持久化線段樹的練習題,目的並不是虐人,而是指導你入門可持久化資料結構。

線段樹有個非常經典的應用是處理rmq問題,即區間最大/最小值詢問問題。現在我們把這個問題可持久化一下:

q k l r 查詢數列在第k個版本時,區間[l, r]上的最大值

m k p v 把數列在第k個版本時的第p個數修改為v,並產生乙個新的數列版本

最開始會給你乙個數列,作為第1個版本。

每次m操作會導致產生乙個新的版本。修改操作可能會很多呢,如果每次都記錄乙個新的數列,空間和時間上都是令人無法承受的。所以我們需要可持久化資料結構:

對於最開始的版本1,我們直接建立一顆線段樹,維護區間最大值。

修改操作呢?我們發現,修改只會涉及從線段樹樹根到目標點上一條樹鏈上logn個節點而已,其餘的節點並不會受到影響。所以對於每次修改操作,我們可以只重建修改涉及的節點即可。就像這樣:

需要查詢第k個版本的最大值,那就從第k個版本的樹根開始,像查詢普通的線段樹一樣查詢即可。

第一行兩個整數n, q。n是數列的長度,q表示詢問數

第二行n個整數,是這個數列

之後q行,每行以0或者1開頭,0表示查詢操作q,1表示修改操作m,格式為

0 k l r 查詢數列在第k個版本時,區間[l, r]上的最大值 或者

1 k p v 把數列在第k個版本時的第p個數修改為v,並產生乙個新的數列版本

對於每個m詢問,輸出正確答案

4 5

1 2 3 4

0 1 1 4

1 1 3 5

0 2 1 3

0 2 4 4

0 1 2 4

4 5 4 4

樣例解釋:

序列版本1: 1 2 3 4

查詢版本1的[1, 4]最大值為4

修改產生版本2: 1 2 5 4

查詢版本2的[1, 3]最大值為5

查詢版本1的[4, 4]最大值為4

查詢版本1的[2, 4]最大值為4

n <= 10000 q <= 100000

對於每次詢問操作的版本號k保證合法,

區間[l, r]一定滿足1 <= l <= r <= n

如題目中演算法詳解,

我的實現:

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7const

int n=10005,m=100005,inf=-2e8;

8struct

nodet[m*10

];11

intgi()

1215

while(ch>='

0' && ch<='

9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();

16return str*f;17}

18int a[n],root[m],tot=0,num=1;19

void build(int &rt,int l,int

r)20

26int mid=(l+r)>>1

;27 build(t[rt].ls,l,mid);build(t[rt].rs,mid+1

,r);

28 t[rt].val=max(t[t[rt].ls].val,t[t[rt].rs].val);29}

30int query(int rt,int l,int r,int sa,int

se)31

37void change(int &rt,int fa,int l,int r,int p,int

to)38

44int mid=(l+r)>>1;45

if(p<=mid)

4650

else

5155 t[rt].val=max(t[t[rt].ls].val,t[t[rt].rs].val);56}

57int

main()

5869

return0;

70 }

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

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

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

這是個非常經典的主席樹入門題 靜態區間第k小。基本思想是像維護字首和一樣,維護每個區間 1.i 中的數,在 1.j 範圍的數的個數。因為大多數狀態是重複的所以我們並不需要開 n 個線段樹,只需要連線到一些沒有改變的子狀態上就可以了。對於查詢區間 ql.qr 內第 k 小的,我們可以判斷,對於當前結點...

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

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