蒟蒻林蔭小複習 Splay

2022-05-08 06:18:12 字數 3026 閱讀 8959

首先表示對yyb大佬的崇高敬意雖然大佬根本不知道林蔭是個神馬東西

在這裡學的:yyb大佬的教程!

好吧,我回來填坑了!

首先宣告一下定義

structp;

p t[

150001];

t陣列就是記錄整顆樹的陣列,v代表當前點的權值,ff代表當前點的父親,ch[0,1]分別代表左右子樹(左子樹上的元素小於根,右子樹則大於),size代表以該節點為根的子樹中元素個數,cnt代表當前點上有多少個元素(權值均為v)pushup維護size

void pushup(int

x)

下面是一次旋轉rotate先想一下一次旋轉會造成什麼影響:假設當前節點為x,父親為y,將x旋轉到y上,x是y的k子樹(k=0或1,代表左右子樹)那麼:

x的k^1兒子會變成y(因為(y>x)==k^1,那麼假如k=0,y>x,那麼將y作為x的右子樹保證大於x,若k=1,y

原來x的k^1兒子被過繼給y做k兒子(假定該兒子為s,若k=0,s>x且s

沒了

然後注意適當的時候維護他們的ff就可以了。

void rotate(int

x)

下面就是splay的核心了,splay,這也是它快的原因splay的作用是將x旋轉成為goal的兒子,若goal==0則將x旋轉到root的位置。現在先想一種情況:

好的,有點大,引用自yyb大佬的部落格。

考慮這種情況,現在我們將x旋轉到root(z)的位置,然後我們查詢b的位置,旋轉前查詢路徑:z—》y—》x—》b

但是旋轉後呢?(自己畫個圖)路徑還是由x—》z—》y—》b,因為這個時候,b作為x的右兒子被過繼給了y,而b的養父y由於被x旋轉下來的z壓著,留在了社會的最底層(批鬥x)這時,樹的深度沒有變化。

然而無論如何向上層社會進步的同時都會付出一定的代價,x向上旋轉的時候b一定會被過繼給y,兩次連續的旋轉後就留在了社會底層,這就不平衡了對吧。那我們就順便提高一波y的社會地位,先將y向上旋轉,這個時候y的左子樹是x,右子樹是z,然後再將x旋轉上去。

可能有的小可愛已經發現了乙個問題,上面所說的問題出現在y和x與自己的父親大小關係相同的情況下,換言之就是x和y同為自己父親的左或者右子樹。

因為如果y和x不同為自己父親的左或右子樹的話,y不會受到x和z旋轉的影響,也就是說y和z在x的不同子樹上,不會出現y被z壓著的情況,這個時候,樹的深度就變淺了hhhhh。

好了,林蔭開始槓精了,如果在把x翻上去之後要查詢z的兒子的話怎麼辦?那就再把z的兒子翻上來不就好啦,翻著翻著樹就變矮變寬了,這也就是平衡樹的精髓所在。

對了,這個時候,如果目標goal==0的話,root就是x啦

void splay(int x,int

goal)

rotate(x);

}if(goal==0

)

}

insert就沒啥好說的了,一溜煙往下找,找到了計數器++,找不到自力更生新開個點

void insert(int

x)

if(t[u].v==x)

else

splay(u,0);

}

find的操作意義是找到權值為x的節點並將其翻到樹頂,也沒啥可說的,一溜煙往下找,找到了就翻上去即可。

void find(int

x) splay(u,0);

}

下面是前驅字尾查詢操作,f=0代表查詢前驅,=1代表查詢字尾。

int next(int x,int

f)

if(t[u].vf)

u=t[u].ch[f];

while(t[u].ch[f^1

])

return

u;}

這裡有一點需要注意,因為find(x)中有splay(u,0)語句了,實際上這個時候u點的權值就是x,這裡是yyb大佬部落格中的乙個小坑,中間兩個if是沒有意義的。

下面是kth(實際上是將序列從小到大排開第k個)這個挺簡單的。

int kth(int

x)

while(1

)

else

else

return

t[u].v;}}

}

最後是delete怎樣刪除乙個可愛的節點,那肯定是將其先變成葉子節點。查詢這個節點的前驅後繼,將前驅旋轉到根,後繼旋轉到成為前驅的兒子,這個時候,目標節點就一定是後繼節點的左兒子並且是葉子節點。那麼就搞死它啦!

void delete(int x)//

刪除x

else

t[next].ch[

0]=0;//

這個節點直接丟掉(不存在了)

}//引用自yyb大佬

完結撒花!

蒟蒻林蔭小複習 K短路的A 解法

看標題都知道講的是什麼,但為什麼特指是a 關於k短路的解法呢?因為林蔭不會其他的。能看到這篇部落格的估計也都知道k短路和a 分別是什麼了吧,下面只介紹一下估價函式 由於林蔭並沒有經過學術訓練,所以一下關於a 的理解均為感性,僅可作為oier速成知識點時的一點資料,切莫作為演算法學術依據。先思考一下,...

蒟蒻林蔭小複習 克魯斯卡爾重構樹

這是乙個冷門到不能再冷門的東西,至於這東西有什麼用,且聽我慢慢道來。現在給定一張無向圖,每個點有乙個點權,每條邊有乙個邊權。現在給出許多詢問三元組 x,y,z 要求求出從x出發,只能走邊權不超過y的邊,所能走到邊權第z大的點的點權是多少?bzoj3551 如果離線的話,大佬們好像可以用主席樹套樹之類...

蒟蒻複習之 Floyd

暴力無解演算法 入門必備 然而我發現這個簡單的演算法還有很多用法 作為複習篇不講原理 圖的要求 既可以是無向圖也可以是有向圖,邊權可以為負,但是不能存在負環 複雜度為o n 3 原理 dp思路 f i j f i k f k j void floyd 注意 1應對所建的圖進行初始化如下 void i...