主席樹 資料結構的克星

2021-10-02 07:07:54 字數 3769 閱讀 8260

1.主席樹:又叫可持續化線段是,因為每次對主席樹的修改,都會重新建立一棵新的數,保留這沒修改之前的歷史紀錄,所以叫可持久化線段樹,她是以線段樹為基礎建立的多棵樹,每棵樹代表著乙個歷史階段,它與線段樹的儲存結構稍微有點不同,就是線段是的左右兩個孩子與根節點都存在這x2,x2+1的關係,而主席樹的根節點與左右孩子兩個節點布村在這種關係,所以要在結構體中在增加兩個變數用來存放兩個根節點的下標。

2.因為主席樹的修改要用到之前的,所以在修改的時候要多傳入乙個變數,即前乙個節點的下標,每次便利到那個節點就新建乙個節點讓它等於前一棵樹的那個節點,所以主席樹每次修改新建的是修改節點到根節點所在的那條鏈上的接點,每次修改只需要新建一條鏈長度的節點,不是新建整棵樹,這樣就節省了很多空間。

3.我感覺主席樹中最燒的操作解釋在建樹和更新時,加的那個引用符,這樣每個節點左右孩子的指向我們就不需要考慮了,引用符號會幫我們解決的。

4.還有乙個與線段樹區別的地方就是當遍歷到懶標記時,進行更新時,要更新左右節點的值,那麼這個時候就要新建節點

void

push_down

(int x,

int l,

int r)

}

兩種不同的建樹方式

void

build

(int

&x,int l,

int r)

int m=

(r+l)

>>1;

build

(tree[x]

.l,l,m)

;build

(tree[x]

.r,m+

1,r)

;push_up

(x);

}

這種建樹方式類似於單點修改單點修改

void

build

(int

&x,int y,

int l,

int r,

int pos)

int m=

(l+r)

>>1;

if(pos<=m)

build

(tree[x]

.l,tree[y]

.l,l,m,pos);if

(pos>=m+1)

build

(tree[x]

.r,tree[y]

.r,m+

1,r,pos)

;push_up

(x);

}

區間的更新

void

update

(int

&x,int y,

int l,

int r,

int ll,

int rr,

int val)

push_down

(x,l,r)

;int m=

(l+r)

>>1;

if(m>=ll)

update

(tree[x]

.l,tree[y]

.l,l,m,ll,rr,val);if

(mupdate

(tree[x]

.r,tree[y]

.r,m+

1,r,ll,rr,val)

;push_up

(x);

}

區間的查詢

int

query

(int

&x,int l,

int r,

int ll,

int rr)

push_down

(x,l,r)

;int m=

(l+r)

>>1;

if(m>=ll) ans+

=query

(tree[x]

.l,l,m,ll,rr);if

(m=query

(tree[x]

.r,m+

1,r,ll,rr)

;return ans;

}

#include

using

namespace std;

typedef

long

long ll;

const

int maxn=

1e5;

struct node

}tree[maxn*40]

;int tot=

0,a[maxn]

;void

push_up

(int x)

void

push_down

(int x,

int l,

int r)

}//這個是先把原來的資料建一棵主席樹

void

build

(int

&x,int l,

int r)

int m=

(r+l)

>>1;

build

(tree[x]

.l,l,m)

;build

(tree[x]

.r,m+

1,r)

;push_up

(x);}/*

//這個是每新增乙個節點,重新建立一棵樹;

void build(int &x,int y,int l,int r,int pos)

int m=(l+r)>>1;

if(pos<=m) build(tree[x].l,tree[y].l,l,m,pos);

if(pos>=m+1) build(tree[x].r,tree[y].r,m+1,r,pos);

push_up(x);

}*/void

update

(int

&x,int y,

int l,

int r,

int ll,

int rr,

int val)

push_down

(x,l,r)

;int m=

(l+r)

>>1;

if(m>=ll)

update

(tree[x]

.l,tree[y]

.l,l,m,ll,rr,val);if

(mupdate

(tree[x]

.r,tree[y]

.r,m+

1,r,ll,rr,val)

;push_up

(x);

}int

query

(int

&x,int l,

int r,

int ll,

int rr)

push_down

(x,l,r)

;int m=

(l+r)

>>1;

if(m>=ll) ans+

=query

(tree[x]

.l,l,m,ll,rr);if

(m=query

(tree[x]

.r,m+

1,r,ll,rr);}

intmain()

資料結構 主席樹

1.p3919 模板 可持久化線段樹 1 可持久化陣列 include define mkp make pair define pb push back define v t vector define all x x.bg,x.ed define newline puts define si x ...

可持久化資料結構之靜態主席樹

參考部落格 前言 如果完全掌握了主席樹的前置知識,主席樹其實也是一種並不算很難的資料結構 雖然蒟蒻還是花了好久 主席樹主要的前置知識就是權值線段樹,一旦理解了權值線段樹的相關知識,那麼主席樹的學習應該也會變得較為簡單。權值線段樹是線段樹的一種,但是它與普通線段樹不同的地方在於,普通線段樹節點的區間代...

資料結構 主席樹 COGS 2211 談笑風生

輸入檔案 laugh.in輸出檔案 laugh.out簡單對比 時間限制 3 s 記憶體限制 512 mb 問題描述 設t 為一棵有根樹,我們做如下的定義 設a和b為t 中的兩個不同節點。如果a是b的祖先,那麼稱 a比b不知道高明到 去了 設a 和 b 為 t 中的兩個不同節點。如果 a 與 b 在...