日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

模板:左偏树

發(fā)布時(shí)間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 模板:左偏树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 解析
  • 可以解決的問(wèn)題
    • 定義:
    • 左偏樹(shù)的基本性質(zhì)
    • 基本結(jié)論
  • 操作
    • 合并
    • 訪(fǎng)問(wèn)與刪除堆頂元素
    • 插入元素
    • 批量插入
    • 刪除已知元素

所謂左偏樹(shù),就是往左偏的樹(shù)

下面介紹一下它的一個(gè)兄弟:

《右偏樹(shù)》
(逃)

解析

所謂左偏樹(shù),確實(shí)就是往左偏的樹(shù)
它舍棄了平衡的性質(zhì),使這個(gè)堆在合并時(shí)變得極為高效
所以又叫做可并堆
代碼實(shí)現(xiàn)起來(lái)還是很好寫(xiě)的

可以解決的問(wèn)題

似乎基本上是起一個(gè)工具人的作用
出現(xiàn)在題解中“…對(duì)于某某信息,維護(hù)可并堆即可”這樣的地方
不會(huì)確實(shí)不行呀 qwq

定義:

外結(jié)點(diǎn) :左兒子或右兒子是空結(jié)點(diǎn)的結(jié)點(diǎn)。
距離 : 一個(gè)結(jié)點(diǎn) x 的距離 dist(x)定義為其子樹(shù)中與結(jié)點(diǎn) x 最近的外結(jié)點(diǎn)到 x 的距離。特別地,定義空結(jié)點(diǎn)的距離為 -1 。

左偏樹(shù)的基本性質(zhì)

左偏樹(shù)具有堆性質(zhì) ,即若其滿(mǎn)足小根堆的性質(zhì),則對(duì)于每個(gè)結(jié)點(diǎn) x 有vx<vlsv_x<v_{ls}vx?<vls?vx<vrsv_x<v_{rs}vx?<vrs?
左偏樹(shù)具有 左偏性質(zhì) ,即對(duì)于每個(gè)結(jié)點(diǎn) x ,有 distlc≥distrcdist_{lc}\ge dist_{rc}distlc?distrc?

基本結(jié)論

結(jié)點(diǎn) x 的距離 distx=distrc+1dist_x=dist_{rc}+1distx?=distrc?+1
距離為 n 的左偏樹(shù)至少有 2n+1?12^{n+1}-12n+1?1個(gè)結(jié)點(diǎn)。此時(shí)該左偏樹(shù)的形態(tài)是一棵滿(mǎn)二叉樹(shù)。
有 n 的結(jié)點(diǎn)的左偏樹(shù)的根節(jié)點(diǎn)的距離是 O(log?2n)O(\log_2 n)O(log2?n)

(以上參考自:https://www.luogu.com.cn/blog/hsfzLZH1/solution-p3377)

上面的性質(zhì)還是比較顯然的
下面我們來(lái)講講具體的操作

操作

合并

左偏樹(shù)的靈魂
設(shè)當(dāng)前是小根堆,要把x堆與y堆合并
首先,如果x、y有一個(gè)為空,直接返回另一個(gè)
否則,把值較小的作為根,把根的右兒子與另一個(gè)堆合并
遞歸即可
遞歸回來(lái)的時(shí)候還要更新dist并維護(hù)左偏的性質(zhì)
由于左偏樹(shù)極右鏈?zhǔn)遣怀^(guò)logn的
因此復(fù)雜度為logn
寫(xiě)起來(lái)也很好寫(xiě)

int merge(int x,int y){if(!x) return y;else if(!y) return x;if(val[x]>val[y]||(val[x]==val[y]&&id[x]>id[y])) swap(x,y);rs[x]=merge(rs[x],y);if(dis[ls[x]]<dis[rs[x]]) swap(ls[x],rs[x]);dis[x]=dis[rs[x]]+1;return x; }

訪(fǎng)問(wèn)與刪除堆頂元素

把堆頂?shù)淖笥覂鹤雍喜⒉⒎祷丶纯?/p> int del(int &x){int res=val[x];x=merge(ls[x],rs[x]);return res; }

插入元素

把一個(gè)元素當(dāng)成一棵樹(shù),與大樹(shù)合并即可

void insert(int &r,int v){int x=New(v);r=merge(r,x); }

批量插入

直接插入n次nlogn
開(kāi)一個(gè)隊(duì)列,把所有元素建成單點(diǎn)的樹(shù)push進(jìn)去
每次從隊(duì)首提兩棵樹(shù)合并并放到隊(duì)尾
直至只剩下一棵樹(shù)
復(fù)雜度O(n)

void build(){queue<int>q;for(int i=1;i<=n;i++){q.push(New(a[i]));}for(int i=1;i<n;i++){int u=q.front();q.pop();int v=q.front();q.pop();q.push(merge(u,v));}r=q.front();q.pop(); }

刪除已知元素

這是一個(gè)左偏樹(shù)的重要優(yōu)勢(shì)
它可以在logn的時(shí)間內(nèi)刪除任意位置的已知元素
注意這里的“已知”是指已知編號(hào)而不是已知權(quán)值
刪除指定權(quán)值的操作是堆很難做到的 (至少對(duì)我的知識(shí)儲(chǔ)備來(lái)說(shuō))
注意樹(shù)的性質(zhì)可能變,所以要一直往上更新

void Del(int x){int f=fa[x];int p=merge(ls[x],rs[x]);fa[p]=f;if(!f){r=p;return;}if(f&&ls[f]==x) ls[f]=p;if(f&&rs[f]==x) rs[f]=p;while(f){if(dis[ls[f]]<dis[rs[f]]) swap(ls[f],rs[f]);if(dis[f]==dis[rs[f]]+1) return;dis[f]=dis[rs[f]]+1;p=f;f=fa[f];}return; }

thanks for reading!

總結(jié)

以上是生活随笔為你收集整理的模板:左偏树的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。