3.一些廢話
4.不知道是不是廢話的話
==**(中考加油!)**==
splay原名伸展樹(splay tree),也叫**樹,是一種二叉排序樹,它能在o(log n)內完成插入、查詢和刪除操作。它由丹尼爾·斯立特(daniel sleator) 和羅伯特·恩卓·塔揚(robert endre tarjan) 在2023年發明的。
伸展樹是一種自調整形式的二叉查詢樹,它會沿著從某個節點到樹根之間的路徑,通過一系列的旋轉把這個節點搬移到樹根去。
新建節點:
int get(int &x,int v,int fa)
讓序列中的第x個數旋轉到根的:
int st(int y,int z)
而在splay裡面,就需要用到雙旋(即對於爺爺,父親和兒子三點共線時,先旋父親,再旋兒子)。
如圖。
圖三先rotate(y),變為:
圖四再rotate(x),變為:
圖五嗯,是這樣吧…
接著就完成了一次雙旋。
然而,對於splay(x,y),我們需要做的是將x旋轉到y的兒子的位置。
所以我們要不斷地旋轉它(x),直到它成為y的兒子。
int splay(int x,int g)
if (!g)
root=x;
}
其實建樹有很多方法,這裡講比較通用的一種。
就是像線段樹一樣從root節點開始,每次分到它的左右兒子去。
int build(int &x,int l,int r,int fa)
當然,還有比較暴力的方法:
1.先建成一條鏈,再通過splay使其盡量平衡。
2.建乙個只有根節點的樹,再不斷插入(insert)節點。
具體視情況而定。
方法一:插入值為x的點,那麼我們可以先找到它的前驅以及後繼,再新建節點,並且將該節點設為前驅和後繼的父親。
方法二:將這個點的前驅設為根,後繼設為根的右兒子,那麼直接在後繼的左兒子處增加這個節點即可。
很好理解吧。
以下**為方法二:
int ins(int x,int y)
由於delete為系統自帶函式,所以改下名。
跟插入的道理其實差不多,將x的前驅旋到更,後繼後繼設為根的右兒子,那麼後繼的左兒子只能為x(證明顯然)。
刪掉就好了。
int del(int x)
其實道理很簡單,就是在splay tree裡找到節點所在的位置,然後直接修改更新就好了。
int replace(int a,int b)
{ int x=root;
a++;
while (size[l]+1!=a)
if (a這個視不同情況而定,很難寫,但是總的來說就是:
比如統計x~y的答案,那麼我們就直接將x旋到根,y的後繼旋到根的左兒子,同理,y的後繼的左子樹即為答案。
splay要盡量打在struct裡,不要問為什麼,常數優化。
對於一些很難維護的東西,要考慮兩點:
是不是可以通過套用其他的演算法或者結構解決。
實在想不到的話,可以先轉化成線段樹式的維護,再通過模擬思想轉移過來。
在維護時,記得該update的地方一定要update(否則正確率擔憂),不該update的地方一定不要update(否則時間擔憂),所以在打splay時一定要考慮清楚了再打。
使用#define可以節省很多**量,也可以節省很多時間。
切記!!!空間一定要開夠,但是不要爆掉!!!必要時可以建乙個棧來存放無用節點,可以節省很多空間。
其實splay也叫spaly…
學習筆記 普通平衡樹Splay
哈哈哈哈哈哈哈終於會打 splay 啦 現在我來發一下 splay 的講解吧 小蒟蒻由於碼風與他人不同,所以自己找了上百篇碼風詭異的 splay 合成的,感謝 zcysky 的 與我碼風相近,讓我看懂了 首先,splay 其實就是把一棵二叉搜尋樹變成一棵深度不會超過 logn 的二叉搜尋樹,它在不斷...
平衡樹學習筆記(3) Splay
splay是乙個實用而且靈活性很強的平衡樹 效率上也比較客觀,但是一定要一次性寫對 debug可能不是那麼容易 splay作為平衡樹,它的平衡方式就是旋轉 暴力旋轉,赤裸裸的旋轉,各種旋轉 就是依靠玄學的旋轉來保證自己的複雜度 不廢話,上主題 struct node 不寫建構函式一時爽,一直不寫一直...
平衡樹之splay
在每次查詢之後對樹進行重構 把被查詢的條目搬移到 離樹根近一些的地方。伸展樹應運而生。伸展樹是一種自調整形式的二叉查詢樹,它會 沿著從某個節點到樹根之間的路徑 通過一系列的旋轉把這個節點搬移到樹根去。大家只需要記住,每次進行插入 查詢的時候,都要把插入 查詢的元素通過旋轉變到根的位置,splay 的...