演算法模版 笛卡爾樹

2022-05-25 22:21:11 字數 1275 閱讀 4342

笛卡爾樹是一種二叉樹,每乙個結點由乙個鍵值二元組 \((k,w)\) 構成。要求 \(k\) 滿足二叉搜尋樹的性質,而 \(w\) 滿足堆的性質。乙個有趣的事實是,如果笛卡爾樹的 \(k,w\) 鍵值確定,且 \(k\) 互不相同, \(w\) 互不相同,那麼這個笛卡爾樹的結構是唯一的。上圖:

(圖源自維基百科)

上面這棵笛卡爾樹相當於把陣列元素值當作鍵值 \(w\) ,而把陣列下標當作鍵值 \(k\) 。顯然可以發現,這棵樹的鍵值 \(k\) 滿足二叉搜尋樹的性質,而鍵值 \(w\) 滿足小根堆的性質。

其實圖中的笛卡爾樹是一種特殊的情況,因為二元組的鍵值 \(k\) 恰好對應陣列下標,這種特殊的笛卡爾樹有乙個性質,就是一棵子樹內的下標是連續的乙個區間(這樣才能滿足二叉搜尋樹的性質)。更一般的情況則是任意二元組構建的笛卡爾樹。

我們考慮將元素按照鍵值 \(k\) 排序。然後乙個乙個插入到當前的笛卡爾樹中。那麼每次我們插入的元素必然在這個樹的右鏈(右鏈:即從根結點一直往右子樹走,經過的結點形成的鏈)的末端。於是我們執行這樣乙個過程,從下往上比較右鏈結點與當前結點 \(u\) 的 \(w\) ,如果找到了乙個右鏈上的結點 \(x\) 滿足 \(x_w,就把 \(u\) 接到 x 的右兒子上,而 x 原本的右子樹就變成 u 的左子樹。

具體不解釋,我們直接上圖。圖中紅色框框部分就是我們始終維護的右鏈:

顯然每個數最多進出右鏈一次(或者說每個點在右鏈中存在的是一段連續的時間)。這個過程我們可以用棧維護,棧中維護當前笛卡爾樹的右鏈上的結點。乙個點不在右鏈上了就把它彈掉。這樣每個點最多進出一次,複雜度 \(o(n)\) 。偽**如下:

新建乙個大小為 n 的空棧。用 top 來標操作前的棧頂,k 來標記當前棧頂。

for i := 1 to n

k := top

while 棧非空 且 棧頂元素 > 當前元素

k--if 棧非空

棧頂元素.右兒子 := 當前元素

if k < top

當前元素.左兒子 := 棧頂元素

當前元素入棧

top := k

笛卡爾樹

維基百科 - 笛卡爾樹

pat笛卡爾樹

笛卡爾樹是一種特殊的二叉樹,其結點包含兩個關鍵字k1和k2。首先笛卡爾樹是關於k1的二叉搜尋樹,即結點左子樹的所有k1值都比該結點的k1值小,右子樹則大。其次所有結點的k2關鍵字滿足優先佇列 不妨設為最小堆 的順序要求,即該結點的k2值比其子樹中所有結點的k2值小。給定一棵二叉樹,請判斷該樹是否笛卡...

笛卡爾樹小結

粗略的學習了一下笛卡爾樹 主要是為了平衡樹打基礎吧 因為關於平衡樹 treap 早忘了 splay 不信任複雜度 然後 我能學一種比較簡單的樹y 笛卡爾樹.這裡以建出小根堆為例。描述區間性質的樹 可以當成二叉搜尋樹不過並不平衡因為每次都是選取當前區間最小值當做為根 然後顯然根據區間的數的排列不同樹的...

笛卡爾 關於笛卡爾

陪孩子看書看到笛卡爾,突然想到了笛卡爾積以及cross join等等,無法忽視的數學之美。關於笛卡爾發明座標系還有這樣乙個故事 有一天,笛卡爾 1596 1650,法國哲學家 數學家 物理學家 生病臥床,但他頭腦一直沒有休息,在反覆思考乙個問題 幾何圖形是直觀的,而代數方程則比較抽象,能不能用幾何圖...