Splay和LCT的複雜度分析

2022-04-30 06:18:07 字數 3481 閱讀 6090

不論插入,刪除還是訪問,我們可以發現它們的複雜度都和\(splay\)操作的複雜度同階,只是一點常數的區別

我們不妨假設有\(n\)個點的\(splay\),進行了\(m\)次\(splay\)操作

採用勢能分析

我們記\(w(x) = \left \lceil \log_2 (size(x)) \right \rceil\),注意以\(2\)為底和上取整

我們定義勢能函式為\(\varphi = \sum w(x)\)

(記第\(i\)次操作操作完之後,勢能為\(\varphi(i)\))

只需要估計出\(\varphi(m) - \varphi(m - 1) + \varphi(m - 1) - \varphi(m - 2) ... + \varphi(1) - \varphi(0) + \varphi(0)\)的大小即可

(即初始勢能和每次的勢能變化量的和)

顯然,\(\varphi(0) \leqslant n \log n\)

\(splay\)操作的具體定義為:

如果父節點是根,那麼旋轉一次

如果父節點和爺節點所處子樹方向一致,那麼先旋轉父親再旋**己

否則,旋轉兩次自己

實際上可以歸結於\(zig\),\(zag\),\(zig-zig\),\(zag-zag\),\(zig-zag\),\(zag-zig\)操作

由於\(zig\)和\(zag\)是對稱的操作

因此,只需要對\(zig\),\(zig-zig\),\(zig-zag\)操作分析複雜度即可

勢能的變化量為\(1 + w'(x) + w'(fa) - w(x) - w(fa) \leq 1 + w'(fa) - w(x) \leq 1 + w'(x) - w(x)\)

勢能變化量為\(1 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g)\)(縮小了常數的影響,但不能無視)

\(\leq 1 + w'(fa) + w'(g) - w(x) - w(fa) \leq 1 + w'(x) + w'(g) - 2w(x)\)

這是神仙複雜度證明中非常神奇的地方,通過一些有趣的性質,讓常數項的代價合併到了勢能的變化中

我們不妨設\(a = w'(g), b = w(x)\),那麼注意到\(w'(x) = a + b + 1\)

由於$2w'(x) - w'(g) - w(x) = \left \lceil \log_2 (a + b + 1) \right \rceil - \left \lceil \log_2 a \right \rceil + \left \lceil \log_2 a + b + 1 \right \rceil - \left \lceil \log_2 b \right \rceil $

注意到\(a, b\)在上式中是對稱的,不妨設\(a \geq b\)

\(\geq \left \lceil \log_2 (a + b + 1) \right \rceil - \left \lceil \log_2 b \right \rceil \geq \left \lceil \log_2 (2b + 1) \right \rceil - \left \lceil \log_2 b \right \rceil \geq \left \lceil \log_2 b \right \rceil + 1 - \left \lceil \log_2 b \right \rceil \geq 1\)

因此有\(1 \leq 2w'(x) - w'(g) - w(x)\),我們將\(1 + w'(x) + w'(g) - 2w(x)\)中的\(1\)放縮,可以得到

勢能變化量為\(1 + w'(x) + w'(fa) + w'(g) - w(x) - w(fa) - w(g) \leq 1 + w'(fa) + w'(g) - w(x) - w(fa) \leq 1 + w'(g) + w'(fa) - 2w(x)\)

由上文的結論,我們知道這裡可以把\(1\)放縮成\(1 \leq 2w'(x) - w'(g) - w'(fa)\)

因此\(\leq 2(w'(x) - w(x))\)

把以上三種操作的勢能全部放縮為\(\leq 3(w'(x) - w(x))\)

不妨假設\(splay\)一次,依次訪問了點\(x_1, x_2 ... x_n\),最後\(x_1\)會成為新的根

那麼,最後的勢能實際上是\(3(w'(x_1) - w(x_1) + w''(x_1) - w'(x_1) + .... + w(n) - w^(x_1)) + 1 = 3 * (w(n) - w(x_1)) + 1\leq log_2 n\)

因此,\(\varphi(m) - \varphi(m - 1) + \varphi(m - 1) - \varphi(m - 2) ... + \varphi(1) - \varphi(0) + \varphi(0) = n \log n + m \log n\)

即\(n\)個點的\(splay\),做\(m\)次\(splay\)操作,複雜度為\(o(n \log n + m \log n)\)

不咕了....

\(lct\)的所有操作可以看做只有\(access\)操作,其他都是常數

那麼\(access\)操作一共有兩部分

首先是在\(splay\)中走的複雜度

定義\(w(x) = \left \lceil \log_2 (size(x)) \right \rceil\),\(size(x)\)指\(x\)的所有虛邊和實邊的子樹大小的和

我們定義勢能函式為\(\varphi = \sum w(x)\)

不妨設它依次訪問了\(x_1, x_2 ..., x_p\)

那麼,類似上文\(splay\)的複雜度分析,我們可以得到總的一次勢能變化量為\(-w(x_1) +w(x_2) - w(x_2) + w(x_3) ... +w(x_p) + 1\leq w(x_p) + 1 = o(\log n)\)

這也就是\(splay\)的\(finger-search\)的性質

初始勢能為\(n \log n\),因此這一部分的複雜度為\(o(n\log n + m \log n)\)

訪問虛邊的複雜度

我們定義勢能函式\(\phi\),為所有重虛邊(兒子的子樹大小大於等於自己的二分之一的虛邊)的數量

那麼,每次訪問至多走\(\log\)條輕虛邊,也就至多帶來\(\log\)條重虛邊,也就是以\(o(\log)\)的代價增加\(\log\)的勢能

而每次訪問一條重虛邊就需要付出\(o(1)\)的代價來減小\(1\)的勢能,並且訪問完重虛邊之後,不會有新的重虛邊產生

因此,最終的複雜度是初始勢能和勢能變化量(實際操作的代價和勢能變化量相同)的和,也就是\(o(n + m \log n)\)

因此,\(lct\)的複雜度為\(o(n \log n + m \log n)\)

複雜度分析 時間複雜度分析和空間複雜度分析

其實,只要講到資料結構與演算法,就一定離不開時間 空間複雜度分析。而且我個人認為,複雜度分析是整個演算法學習的精髓,只要掌握了它,資料結構和演算法的內容基本上就掌握了一半。1.時間複雜度分析 對於剛才羅列的複雜度量級,我們可以粗略地分為兩類,多項式量級和非多項式量級。其中,非多項式量級只有兩個 o ...

時間複雜度和空間複雜度分析

演算法是指用來運算元據 解決程式問題的一組方法。對於同乙個問題,使用不同的演算法,也許最終得到的結果是一樣的,但在過程中消耗的資源和時間卻會有很大的區別。那麼我們應該如何去衡量不同演算法之間的優劣呢?主要還是從演算法所占用的 時間 和 空間 兩個維度去考量。接下來主要介紹時間複雜度和空間複雜度的計算...

時間複雜度和空間複雜度分析

如何評價一段 或演算法的效能和好壞?目前衡量 質量的指標主要有兩個 分別為時間複雜度和空間複雜度。其中時間複雜度指的是執行當前演算法所消耗的時間,空間複雜度指的是指執行當前演算法需要占用多少記憶體空間。有的時候時間和空間是不可兼得的,需要從中去取乙個平衡點。下面簡單描述一下如何計算時間複雜度和空間複...