$fhq\_treap$是平衡樹的一種,它不僅支援幾乎所有的平衡樹的操作,而且實現特別簡單,總共只有兩個操作。這裡來簡單介紹一下。
$fhq\_treap$和$treap$一樣是需要用隨機值來維護樹的形態的,但是$fhq\_treap$不需要旋轉來調整形態,而是用$split$和$merge$來實現,也就是分離與合併,也就是這兩種操作,完成了$fhq\_treap$的所有操作。
分離(split)
把一棵平衡樹分離成兩棵,從而方便插入和刪除。分離有兩種做法,一種是按權值分離,一種是按子樹大小分離,根據情況選擇。
權值分離版:
void split(int rt,int k,int &x,int &y)}
子樹大小版:
void split(int rt,int k,int &x,int &y)else
pushup(rt);
}}
合併(merge)
合併操作與左偏樹的合併類似,按照優先順序合併,把優先順序高的作為父節點。當然,合併的時候,函式中的兩個引數$x,y$要按照順序,$x$是權值較小的,$y$是權值較大的,因為合併的時候是按照隨機值來確定優先順序的。(當然在函式中交換也行,不過常數大些)
int merge(int x,inty)else
}
插入新節點(insert)
先把樹按照新結點的權值分離,然後再把新結點當作一棵樹與兩個分離出來的樹合併。
inline int neo(intv)inline
void insert(int
v)
刪除節點(delete)
按刪除節點的權值$v$把樹分離成小於$v$,等於$v$,大於$v$三段,然後去掉等於$v$的樹的根節點(也就是直接合併根節點的左右子樹),然後合併回來。
inline void delet(intv)
查詢權值為$k$的節點排名
按照權值分離然後輸出左子樹大小$+1$即可。
inline void kth(intk)
查詢$k$小值
和其他平衡樹一樣搜尋、遞迴。
int rank(int rt,intk)
查詢前驅後繼
按權值分離然後查詢分離出的子樹的最大/最小值就行了。
inline void prev(intv)inline
void nex(int
v)
可以看出,$fhq\_treap$的操作都非常簡短,僅僅用了兩種核心操作就實現了其他平衡樹的能實現的全部功能,非常方便。在絕大多數情況下需要使用平衡樹的時候都可以直接用$fhq\_treap$,既容易理解又方便實現,而且也很容易$debug$。
同時,$fhq\_treap$也是支援可持久化的,不過這裡就不再贅述(我會告訴你其實我也沒寫過?)。
洛谷模板題
//it is made by holselee on 27th sep 2018
p3369
#includeusing
namespace
std;
const
int n=1e5+7
;int
n,root,tot;
int val[n],ch[n][2
],p[n],siz[n];
inline
intread()
while( ch>='
0' && ch<='9'
)
return flag ? -num : num;
}inline
void pushup(int
rt)void split(int rt,int k,int &x,int &y)
}int merge(int x,inty)
else
}inline
int neo(int
v)inline
void insert(int
v)inline
void delet(int
v)inline
void kth(int
k)int rank(int rt,int
k)inline
void prev(int
v)inline
void nex(int
v)int
main()
return0;
}
FHQ Treap小結(神級資料結構!)
首先說一下,這個東西可以搞一切bst,treap,splay所能搞的東西 今天心血來潮,想搞一搞平衡樹,思路比較好理解,但是 量。一看就頭大,然後,在洛谷翻題解的時候無意間看到了遠航之曲發的一篇非常短小精悍的題解,於是就學了一下 這個東西的學名應該是叫做fhq treap,應該是treap的強化版。...
資料結構 資料結構緒論
資料結構是相互間存在一種或多種特定關係的資料元素的集合。程式設計 資料結構 演算法 資料結構是一門研究非數值計算的程式設計問題中的操作物件,以及他們之間的關係和操作等相關問題的學科。資料元素是組成資料的 有一定意義的基本單位,是計算機中通常作為整體處理,也被稱為記錄。乙個資料元素可以由若干個資料項組...
資料結構 資料結構演算法
分治法 對於乙個規模為n的問題,若該問題可以容易地解決 比如說規模n較小 則直接解決 否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞迴地解這些子問題,然後將各子問題的解合併得到原問題的解。動態規劃法 這種演算法也用到了分治思想,它的做法是將問題例項分解為更小的 相似的子...