Splay學習筆記

2022-08-22 03:24:15 字數 1294 閱讀 1036

n(n<=500000)個數,要求維護區間加,區間查詢

很簡單,用線段樹/樹狀陣列隨便寫寫就能過

n(n<=500000)個數,維護插入、刪除、找區間第k大/小

用平衡樹/set也能過

n(n<=500000)個數,維護區間翻轉,區間查詢,插入,刪除

這個時候就需要用到伸展樹(splay)

splay是一種極(常)靈(數)活(大)的資料結構,它能夠維護線段樹的部分操作和平衡樹的操作

它的美妙之處在於能夠旋轉,從而完成一系列操作

它的旋轉和平衡樹的只轉一次不同,它可以進行雙旋操作來保證較優秀的時間複雜度(但常數還是大)

雙旋操作是基於單旋的

首先是單旋:

和平衡樹相同

然後是雙旋:

當p不是根節點,且x和p同為左孩子或右孩子時進行zig-zig操作。

當x和p同為左孩子時,依次將p和x右旋;

當x和p同為右孩子時,依次將p和x左旋。

當p不是根節點,且x和p不同為左孩子或右孩子時,進行zig-zag操作。

當p為左孩子,x為右孩子時,將x左旋後再右旋。

當p為右孩子,x為左孩子時,將x右旋後再左旋。

有了單旋和雙旋就可以進行splay操作:

int get(int o)

void rotate(qaq o)

void splay(int o,int goal)

if(!goal) rot=o;//換根

push_up(o);

}

進行區間操作[l,r]時,常常把節點l-1轉到根,r+1轉到根的右兒子,這樣根的右兒子的左兒子就是操作區間 ,並且常常新增虛擬節點0和n+1來進行[1,n]的操作

區間翻轉就直接交換左右兒子

區間加直接加lazy標記

還能查詢某乙個值的排名:找到節點,轉到根,根的做兒子大小+1就是排名

注意:splay中有些操作不能同時進行,例如求第k大和區間操作就不能同時進行,因為前一種操作改變了原序列順序,後乙個操作要求不能改變,這樣就發生衝突。splay旋轉僅僅是改變樹的形狀,並沒有改變原序列順序(樹的中序遍歷)

splay 學習筆記

核心函式splay 每次訪問乙個節點,都把該節點轉到根 包括插入 查詢 操作 思想 對於訪問頻率較高的節點,使其處於根節點附近,從而保證log複雜度 splay可以維護中序遍歷是有序序列 也可維護 中序遍歷是當前操作後的序列 const int n 1e5 10 struct nodet n int...

Splay學習筆記

一種二叉樹的樹形資料結構,其定義如下 一種自平衡二叉搜尋樹,通過不斷將某個節點旋轉到根節點,使得整棵樹仍然滿足二叉查詢樹的性質,且保持平衡而不至於退化為鏈 root tot fa i child i 0 1 val i cnt i size i 根節點節點總數 父親左右兒子 點權出現次數 子樹大小 ...

學習筆記 splay入門(更新中)

宣告 本部落格所有隨筆都參照了網路資料或其他部落格,僅為博主想加深理解而寫,如有疑問歡迎與博主討論 終於學習了 spaly splay 聽說了很久,因為dalao總是那這個開玩笑所以對它有深深的恐懼.但是學起來沒有那麼難啦,可能是因為提前學了替罪羊樹?學替罪羊樹真的是痛苦555 p3369 模板 普...