[學習筆記]笛卡爾樹

笛卡爾樹Cartesian Treehtml

前言

符合:祖先權值優先級更高,中序遍歷是序列自己數據結構

類比treap,只不過不平衡post

 

既然不如treap平衡,支持操做就少了。優化

那麼支持的操做,複雜度必需要更優了。url

 

建樹

增量法spa

i=1~nhtm

用單調棧維護最右邊路徑上的點blog

加入i點,從底向上找到第一個能放的位置,放上去,從棧中彈出的鏈就是左兒子。get

中序遍歷性質顯然能夠保證it

權值優先級顯然能夠保證

O(n)

(因此Treap也能夠O(n)建樹)

 

例題:

求最大矩形

 

1.單調棧直接作。

2.創建小根堆笛卡爾樹,每一個點的貢獻是:子樹sz*高度。正確性顯然

 

例題2:

 bzoj2616: SPOJ PERIODNI——笛卡爾樹+DP

 

例題3:

• 對於任意排列,定義其權值爲:
• 首先求出排列的笛卡爾樹
• 對於樹上有兩個兒子的節點,設兒子的下標位置爲 𝑎 和 𝑏
• 版本一:其對權值的貢獻爲 |pa-pb|
• 版本二:其對權值的貢獻爲 |𝑎 − 𝑏|
• 假設排列等機率隨機,求權值的指望
• 𝑛 ≤ 100

兩種不一樣的思路:

版本一:

 

關心兒子位置,

f[i][j]大小爲i的樹,根節點在j位置權值

枚舉左兒子和右兒子的位置a,b,再分配編號:C(i-1,a)

能夠把f[i][a]+a之類放在一塊兒進行前綴和優化

純粹從計數考慮,還要維護方案數

 

個數從小到大擴展,位置合併並分配編號

還有相對設法

 

版本二:

權值絕對值要去掉,從小到大加入

大的樹就是放到葉子了

拼接的時候貢獻還要考慮父親權值很差處理

若是有些點必然會有葉子,那麼放下一個權值以前,這些位置直接貢獻cnt的答案

相似放書那個題

f[i][j][k]放了前i個數,有j個位置還少兩個葉子,k個位置還少一個葉子(對將來承諾!)

 

合併

%%immortalCO

數據結構雜題集第三個有提到

定義關鍵點:一個樹最左邊和最右邊兩個鏈

關鍵點只有初始的O(n)個

合併x,y時候,對於x的右鏈和y的左鏈,從最底下開始往上找到第一個能放的位置,這一段長度設爲len

以後這段關鍵點會被覆蓋住,再也不存在。

而後y的這個點左兒子和x的這個點的右兒子進行相似fhq的合併,也就是通常的暴力合併

因爲路徑上的點就是兩個段的關鍵點

關鍵點而後就消失了。

走的長度就是關鍵點減小的個數

因此均攤O(n)

從最底下開始找,能夠用鏈表而後鏈表合併。單純記錄每一個點最右邊的點也能夠

sz什麼的pushup就找到了。

(pushup這個不太好找到,最開始一段鏈很難搞。能夠用LCT同時和笛卡爾樹合併作,用於打上標記)

挺trick的

 

感悟

具備「treap」的兩個性質

對於須要支持操做比較簡單的題目,尤爲對於序列上有關大小的問題,笛卡爾樹的優秀結構可使得處理有計可施

相關文章
相關標籤/搜索