範浩強treap 可持久化

2022-03-27 08:53:37 字數 1497 閱讀 2020

當平衡樹需要可持久化的時候,意味著我們需要訪問以前的某個時間點的平衡樹,就要保持以前的樹形態不變,新建乙個時間戳,構建一棵新的樹。

如果用以前的旋轉treap可能就不方便做到(又要打時間戳,又要新建節點,又要旋轉),而且涉及到旋轉,空間可能會承受不住,我們需要用到一種新的平衡樹——fhq treap

這是一種非常好寫的treap 核心操作有兩個,乙個是split乙個是merge。

split(node,k,x,y) 意思是把以node為跟的子樹分成兩部分,一部分小於等於k(根為x),一部分大於k(根為y)。在可持久化的時候要保證以前的樹的形態不變,就要每一次copy乙個節點過來。

而我們每一次遞迴只會訪問乙個節點的左右子樹中的乙個節點,又因為treap的均攤深度為log,所以總體的空間為nlogn,是非常高效的。

說完split接下來是merge

merge函式,是有返回值的,merge(x,y) 是把以x為根的子樹和以y為根的子樹合併起來,返回這棵新的樹的根,遞迴的實現,非常好懂。

接下來的所有操作都是基於以上兩個核心的操作,非常好理解,比旋轉的treap好理解而且更好寫,注意可持久化即可。

——by vane

1 #include2

using

namespace

std;

3const

int n=500005;4

struct

node

5t[n*50];9

int root[n],cnt=1;10

int copynode(int

x)11

16void update(int

cur)

1721

int newnode(int

val)

2230

void split(int now,int k,int &x,int &y)

3140

else

4145

update(x);

46update(y);47}

48}49int merge(int x,int

y)50

59else

6066}67

void insert(int bb,int

val)

6875

void delete(int bb,int

val)

7683

int getpos(int now,int

k)8491}

92int getkth(int bb,int

val)

93100

int getval(int now,int

k)101

106int getpre(int bb,int

val)

107116

int getnext(int bb,int

val)

117124

intmain()

125141

}142 }

可持久化Treap

本來是想寫一點題的,但是hfu最近讓我改鍵盤指法,原來都是亂打 手速蠻快就是錯的多 剛開始練手法真的煩躁,像我這種從來不用小指頭的 就寫個學習筆記吧.非教程向,只是懂了後寫點隨筆,練成指法說不定能來填坑.可持久化treap首先是基於非旋轉式treap的,如果要旋轉的話那麼就會破壞父子關係導致無法可持...

可持久化Treap

可持久化treap本質上市乙個二叉平衡樹,若不對其規則進行修改,中序遍歷後得出的序列是遞增的。void maintain o 計算結點o的size int lowcount key 比key所在位置小1 int uppercount key key所在的位置,如果有多個相同的key,選位置最大的 i...

LOJ 持久化序列 可持久化treap

一道模板題 在寫完這道題以後就去找其他帶翻轉的可持久化treap題去寫了 發現自己根本不會可持久化treap 什麼標記翻轉可持久化 自閉了一整天 網上也沒有找到很好的模板 於是選擇擱置一段時間 等以後時間充裕了再來磕 includeusing namespace std const int maxn...