treap的本質是一顆二叉查詢樹,只是在每個結點上都附加了乙個優先順序的資訊。保證每個點的優先順序都比左右兒子小,利用優先順序,我們可以把這顆樹看成乙個小根堆。
treap樹在隨機給優先順序的情況下,可以在期望o(logn)的時間複雜度裡完成:
以上四種操作。
那麼話不多說,先上模板。這裡準備了兩個模板,第乙個來自紅書,**量89行(有三個冗餘函式居然還短些),第二個據說來自劉汝佳的《訓練指南》,**量99行但是變數名比較短,或許打起來可以更快些。
第乙個模板:
#include
using
namespace
std;
const
int maxnode = 444444;
const
int inf = 0x3f3f3f3f;
struct treap
void update(int x)
void rotate(int &x, int t)
void __insert(int &x, int k) else
}} else
update(x);
}void __erase(int &x, int k) else
int t = priority[childs[x][0]] > priority[childs[x][1]];
rotate(x, t);
__erase(x, k);
}} else
update(x);
}int __getkth(int &x, int k)
k -= size[childs[x][0]] + cnt[x];
if(k <= 0)
return __getkth(childs[x][1], k);
}void insert(int k)
void erase(int k)
int getkth(int k)
};int main()
注釋詳見紅書190頁。
第二個模板:
#include
#include
#include
#include
using
namespace
std;
struct node
int cmp(int x)
void maintain()
}; //root全域性使用的話可以在這裡跟上*root
void rotate(node* &o,int d)
void insert(node* &o,int x)//o子樹中事先不存在x
o->maintain();
}void remove(node* &o,int x)
else
}else remove(o->ch[d],x);
if(o) o->maintain();//之前o存在,但是刪除節點後o可能就是空null了,所以需要先判斷o是否為空
}//返回關鍵字從小到大排序時的第k個值
//若返回第k大的值,只需要把ch[0]和ch[1]全互換就可以了
int kth(node* o,int k)
//返回值x在樹中的排名,就算x不在o樹中也能返回排名
//返回值範圍在[1,o->s+1]範圍內
int rank(node* o,int x)
int main()
int v;
while(scanf("%d",&v)==1)
}return
0;}
個人更加喜歡第二個模板,並用它ac了一道模板題:poj 2985
簡要題意:有n只貓,開始每只貓都是乙個小組,下面要執行m個操作,操作0 i j 是把i貓和j貓所屬的小組合併,操作1 k 是問你當前第k大的小組大小是多少. 且k<=當前的最大組數。
思路:並查集+treap,並查集維護集合合併,treap負責查詢第k大。可以只把合併後的組扔到treap裡,做乙個優化。
ac**:
#include
#include
#include
#include
#include
using
namespace
std;
struct node
int cmp(int x)
void maintain()
} *root;
void rotate(node* &o,int d)
void insert(node* &o,int x)//o子樹中事先不存在x
o->maintain();
}void remove(node* &o,int x)
else
}else remove(o->ch[d],x);
if(o) o->maintain();//之前o存在,但是刪除節點後o可能就是空null了,所以需要先
判斷o是否為空
}//返回關鍵字從小到大排序時的第k個值
int kth(node* o,int k)
//返回值x在樹中的排名,就算x不在o樹中也能返回排名
//返回值範圍在[1,o->s+1]範圍內
int rank(node* o,int x)
const
int maxn = 2e5 + 5;
int far[maxn], rnk[maxn], siz[maxn];
int find(int x)
void unite(int x, int y)
int main()
root = null;
while(m--) else
}return
0;}
據說這道題可以用樹狀陣列來a,而且**比treap短,我再去學習一波~ 資料結構 Treap的實現與應用
treap的本質是一顆二叉查詢樹,只是在每個結點上都附加了乙個優先順序的資訊。保證每個點的優先順序都比左右兒子小,利用優先順序,我們可以把這顆樹看成乙個小根堆。treap樹在隨機給優先順序的情況下,可以在期望o logn 的時間複雜度裡完成 以上四種操作。那麼話不多說,先上模板。這裡準備了兩個模板,...
資料結構 Treap
前兩天看了byvoid大神寫的treap的 中幾乎給出了所有的 不過最後一部提到了乙個優化,就是對於重複的元素採用在同乙個節點中記錄乙個weight來記錄者個元素使用了多少次的寫法,以及查詢第k個數的功能的實現,我試著寫了乙個,表示樹旋轉之後需要重新設定size有一點點煩。因為找不到合適的題目去測試...
資料結構之Treap
1.概述 同splay tree一樣,treap也是乙個平衡二叉樹,不過treap會記錄乙個額外的資料,即優先順序。treap在以關鍵碼構成二叉搜尋樹的同時,還按優先順序來滿足堆的性質。因而,treap tree heap。這裡需要注意的是,treap並不是二叉堆,二叉堆必須是完全二叉樹,而trea...