顧名思義,treap就是tree+heap,複雜度與splay的均攤log
loglo
g不同,treap是期望log
loglo
g,但與splay比起來,功能都差不多,但**的長度和除錯難度都比spaly要舒服很多,
treap是一棵二叉查詢樹,與普通的二叉查詢樹不同,對於每個節點,它還記錄乙個隨機值rdrd
rd,滿足,如果只看rdrd
rd的話,它就是乙個堆,
這樣,它的期望深度就是log
loglo
g的,每次的查詢修改直接在上面跑也沒問題。
以下為treap的基本操作,各種在這上面擴充套件出的其他的操作這裡就不細講了
我們可以發現一棵treap同時也是一棵迪笛卡爾樹,
那麼建樹就可以o(n)解決了,用乙個棧即可,
(當然你像插入一樣做也沒問題)
//b[i].rd為位置i的隨機值
//merge()為標記的合併,
void
build
(int q)
void
build_treap()
if(i>n)
break
; b[i]
.l=la;
b[la]
.fa=i;
za[++za[0]
]=i;
} root=n;
build
(root)
;}
treap當然離不開split操作啦,
這個點操作的作用是把treap兩棵treap,一半為前si個,另一半就是剩下的,
具體的操作是:判斷斷開的位置是在左子樹還是右子樹,再遞迴求解,
(看標的話理解的會快一點)
//merge()為標記的合併,
typedef pair<
int,
int> trp;
trp split
(int q,
int si)
else
merge
(q);
return t;
}
合併就簡單了,直接把較大的那個放到這個位置即可
//因為merge函式被標記合併占用了,所以只能用另乙個詞了
intamalgamate
(int q,
int w)
b[w]
.l=amalgamate
(q,b[w]
.l);
merge
(w);
return w;
}
資料結構 Treap
前兩天看了byvoid大神寫的treap的 中幾乎給出了所有的 不過最後一部提到了乙個優化,就是對於重複的元素採用在同乙個節點中記錄乙個weight來記錄者個元素使用了多少次的寫法,以及查詢第k個數的功能的實現,我試著寫了乙個,表示樹旋轉之後需要重新設定size有一點點煩。因為找不到合適的題目去測試...
資料結構之Treap
1.概述 同splay tree一樣,treap也是乙個平衡二叉樹,不過treap會記錄乙個額外的資料,即優先順序。treap在以關鍵碼構成二叉搜尋樹的同時,還按優先順序來滿足堆的性質。因而,treap tree heap。這裡需要注意的是,treap並不是二叉堆,二叉堆必須是完全二叉樹,而trea...
模板 資料結構 Treap
還有人把treap叫做樹堆的,但是常用名還是叫做treap的比較多。不進行任何封裝的,帶求和操作的,乙個節點存放多個元素的最普通的treap。includeusing namespace std typedef long long ll define ls ch id 0 define rs ch ...