P3369 平衡樹treap模板

2021-08-19 14:35:58 字數 1306 閱讀 5309

第一次學,調了兩天

乙個操作乙個操作的講

插入,這個沒啥好說的,將乙個點插入樹中,定義乙個insert(int &o,int v)函式,o傳的引用,改變o值時,root也會跟著改變,先判斷當前傳入值是否存在值,即當前o是否等於0,等於0則沒有用過,初始化乙個prio=rand(),即給當前插入點隨機附乙個優先順序,防止出題人對著你卡資料把你卡成一條鏈,用prio來旋轉,初始當前點的size為1;

push_up操作,更改當前修改點的size,即子樹大小,當前點的子樹大小等於左兒子子樹大小+右兒子子樹大小+1

rotate旋轉,向右旋轉則把當前點接在他的左兒子的右子樹上,來確保中序遍歷不變,中序遍歷的意思是優先走左子樹走到葉子節點後開始回溯輸出,輸出結果一定是公升序,自己手摸,向左旋轉同理,轉完之後更新兩個節點的size

remove刪除操作,先找到值為當前刪除點的點的標號,然後先看當前點的左右子樹哪個為空,然後就把他和另乙個子樹交換位置,直到當前點成為葉子節點,然後刪掉它,如果都不為空,判斷哪科子樹優先順序更小,就與那棵子樹進行交換,直到換到葉子節點,過程中注意要保證中序遍歷,隨時更新size

大於等於的最小值,和線段樹相似,隨機從乙個點進入,然後比較他的val與當前查詢值得大小,小於則搜右子樹,反之則搜尋左子樹然後和當前點取min

小於等於的最大值,與上乙個操作相似,只不過把第二種情況換成取max

獲取當前值的排名,隨機進入,比較大小,小的話,則說明在當前點的前面,搜尋右子樹,加上左子樹大小還有當前點的1,否則搜尋右子樹

獲取排名為k的值,說白了求第k大,與上面實現相反,判斷子樹大小與排名的關係,bulabula,嗯,

上**

//by acer.mo

#include#include#include#include#includeusing namespace std;

const int max_n = 3e5 + 10;

const int inf = 0x3f3f3f3f;

struct node

;node t[max_n];

int pool_cur;

int del_pool[max_n], del_cur;

int root;

void init()

void push_up(int o)

int getrank(int o,int v)

int find_kth(int o, int k)

return 0;

}

P3369 模板 普通平衡樹 Treap

插入x數 刪除x數 若有多個相同的數,因只刪除乙個 查詢x數的排名 排名定義為比當前數小的數的個數 1。若有多個相同的數,因輸出最小的排名 查詢排名為x的數 求x的前驅 前驅定義為小於x,且最大的數 求x的後繼 後繼定義為大於x,且最小的數 輸入格式 第一行為n,表示操作的個數,下面n行每行有兩個數...

洛谷P3369 模板 普通平衡樹 Treap

插入xxx數 刪除x xx數 若有多個相同的數,因只刪除乙個 查詢x xx數的排名 排名定義為比當前數小的數的個數 1 1 1。若有多個相同的數,因輸出最小的排名 查詢排名為x xx的數 求x xx的前驅 前驅定義為小於x xx,且最大的數 求x xx的後繼 後繼定義為大於x xx,且最小的數 總算...

洛谷P3369 模板 普通平衡樹 treap

編寫乙個資料結構在每次 o logn 1 leq n leq 1e6 完成以下功能 一 插入乙個數到序列中 二 在序列中刪除某乙個數 三 找到第 k 大 四 詢問第 k 大的數 五 找到 x 的前驅,六 找到 x 的後繼。很顯然,二叉搜尋樹就可以完成這個任務,不過最壞情況下,二叉樹會退化成鏈,就會超...