bzoj 3224,tyvj 1728普通平衡樹

2021-07-10 16:16:23 字數 2171 閱讀 5626

原題位址

這道題涵蓋了平衡樹的基本操作。。。

先關注操作三,它指出要輸出最小的排名,因此我們可以將重複的元素存在乙個節點內,**實現很簡單。。。

插入操作已講。。。

那麼怎樣刪除呢?

首先我們找到被刪的點,如果它是重複的(該元素還剩很多個),那麼就把個數減一即可。

否則我們可以採用像堆的方式,將這個元素通過旋轉不斷地下移。。。

問題來了,下移的時候是選擇左旋還是右旋呢?

左旋是將右邊的點換到上面,右旋是將左邊的點換到上面,由於我的隨機值是大根堆(大的在下,小的在上)。那麼我就應該把隨機值小的兒子旋到上面來。(和堆的原理一樣)根據這個來決定是左旋還是右旋。。旋轉後將當前點移動到旋轉的那個兒子上[旋轉後原來的點就變成了兒子,兒子正是原來的點];就這樣反覆執行,直到當前點的兩個兒子都為null 了[注:null是本人造出來的值,為了彌補指標的不足,具體詳見**] ,就把當前點變為null,就成功刪去啦!

怎樣用平衡樹來查前驅呢?

如果我們要查點x的前驅,從root開始, 如果當前點的值是小於x點的,那麼前驅有可能在當前點的右子樹中,但當前點的的右子樹中的所有點可能都大於x點,所以前驅也有可能就是當前點。。。面對這種情況我們應先搜右子樹,看有沒有結果,然後確定答案;如果當前點是大於等於x點的,那麼很顯然前驅在當前點的左子樹中,就把當前點變為左兒子就行了

查後繼的事情就交給讀者自己想了。

至於3,4兩個查詢操作,對於讀者來說也很簡單了,就不說了。。

那麼基本的treap模板就打出來了

#include#include#include#include#include#include#include#include#includeconst int n = 1e5 + 7,inf = 0x7fffffff;

#define ran1221() ((rand() << 13) + (rand() << 6) + rand ())

#define ran12() (ran1221() + ran1221() + ran1221() + 1)

class treap

node (int data,node *fl) : data(data)

void update ()

}*pool,*null,*root,meme[n];

int ball;

void rotate (node *&t,bool v)

int precursor (node *&t)

int subsequent (node *&t)

void print (node *&t)

void insert (node *&t)

if(t -> data == ball)

int v = ball > t -> data;

insert (t -> son[v]);

if(t -> son[v] -> hr < t -> hr) rotate (t,v);

else t -> update();

} int sum;

void rank (node *&t)

} void delete (node *&t)

if(t -> son[0] == null || t -> son[1] == null)

int v = t -> son[1] -> hr < t -> son[0] -> hr;

rotate (t,v);

delete (t -> son[v^1]);

} else

t -> update();

} int theno (node *&t)

public :

treap ()

void pri ()

void clear ()

void ins (int ***)

int ran (int ***)

void del (int ***)

int the (int ***)

int pre (int ***)

int sub (int ***)

}treap;

int opt,w,q;

int main ()

return 0;

}

that is all , thank you for watching.

BZOJ 3224 Tyvj 1728 普通平衡樹

description 您需要寫一種資料結構 可參考題目標題 來維護一些數,其中需要提供以下操作 1.插入x數 2.刪除x數 若有多個相同的數,因只刪除乙個 3.查詢x數的排名 若有多個相同的數,因輸出最小的排名 4.查詢排名為x的數 5.求x的前驅 前驅定義為小於x,且最大的數 6.求x的後繼 後...

BZOJ3224 Tyvj1728普通平衡樹

題意 寫一種資料結構,來維護一些數,其中需要提供以下操作 1.插入x數 2.刪除x數 若有多個相同的數,因只刪除乙個 3.查詢x數的排名 若有多個相同的數,因輸出最小的排名 4.查詢排名為x的數 5.求x的前驅 前驅定義為小於x,且最大的數 6.求x的後繼 後繼定義為大於x,且最小的數 ps.題目題...

BZOJ 3224 Tyvj 1728 普通平衡樹

都是平衡樹的基本操作 愛splay的spaly 愛treap的terap 我剛學了替罪羊樹來練練。插入及子樹的重構看這篇bzoj 1588 hnoi2002 營業額統計 刪除操作 先找到節點位置,然後如果該點只有乙個兒子,就直接用其兒子替換改點,否則找到其前驅替換該點,然後刪除其前驅 注意如果刪了總...