模板 左偏樹

2022-04-30 18:30:10 字數 1698 閱讀 4299

左偏樹是一棵二叉樹,也是一種可並堆,擁有堆的性質,可以像堆一樣合併。

左偏樹顧名思義,有「左偏」的特點,既每個左子樹節點的\(dist\)一定大於等於右子樹節點的\(dist\)。

由性質2可得:\(t[x].d=t[t[x].ch[1]].d+1\)

同時,我們需要注意左偏樹的\(dist\)並不意味著深度,跟深度無關。

講了這麼久\(dist\),那麼\(dist\)到底是什麼?

對於乙個二叉樹,我們定義乙個節點的\(dist\)為它到離它最近的葉子節點的距離+1,葉子節點的\(dist=1\),空節點的\(dist=0\)

詳細見**注釋

int& rs(int x)//求右兒子

找到\(x\)所在堆的最小值/最大值,用並查集實現,接著合併\(x\)的左右子樹

int find(int x)

void pop(int &x)

注意:這裡是刪除任意編號節點,而不是任意權值節點,左偏樹不支援刪除任意權值節點

我們先合併\(x\)的左右兒子

接著更新\(x\)的父親和\(f[x]\)的兒子

因為這樣合併更新可能會破壞左偏的性質,所以需要遍歷檢查滿不滿足左偏性質,更新,直到滿足左偏性質就可以結束或者到達根節點

void pushup(int x)

}int merge(int x,int y)

void del(int x)

新建乙個節點,將其初始化為\(x\)

因為這個節點也可以視為乙個堆,可以直接合併

void push(int &rt,int v)

在根\(x\)上打標記,然後每一次合併堆或者刪除根時下傳

void pushdown(int x)//這裡以加上乙個數為例

}

模板題洛谷p3377 【模板】左偏樹(可並堆)

洛谷p2713 羅馬遊戲

給出洛谷p2713 羅馬遊戲的**

#includeusing namespace std;

const int n=1000010;

struct tree

t[n];

int n,q;

int f[n];

bool dead[n];

int& rs(int x)

int find(int a)

char op[10];

int main()

scanf("%d",&q);

while(q--)

else

a=find(a);

dead[a]=1;

f[a]=f[t[a].ch[0]]=f[t[a].ch[1]]=merge(t[a].ch[0],t[a].ch[1]);

printf("%d\n",t[a].val);

} }return 0;

}

例題

【xsy1985】【bzoj1367】【baltic2004】sequence

【xsy2488】【hdu5818】joint stacks

深深感覺到自己的渺小

左偏樹 模板

神經病也可以寫成右偏樹 具體左偏指左節點的距離 geq 右節點的距離 距離指離最近擁有空節點的節點的距離 乙個節點的值一定 或 leq 或 geq 或 其子節點的值 由於左偏性質,每次可以合併至右邊,維護左偏性質後就可以保證複雜度 被踩爆的板子 或者是我?include define ls lson...

模板 左偏樹

洛谷模板題 一聽左偏樹這個名字就感覺左偏。左偏樹是什麼,好像就是個堆,大根堆或小根堆,可以支援合併,取堆頂元素,刪除堆頂元素,插入元素的操作。一些說明 左偏樹節點除了應有的東西,還有鍵值和距離,鍵值用於比較大小,距離是什麼?距離是這樣定義的 節點i稱為外節點 external node 當且僅當節點...

模板 左偏樹

可在log複雜度合併的堆 每個節點有乙個距離,具體定義我不知道 1.滿足堆的性質 2.左子節點距離 右子節點 3.節點距離 右子節點距離加1 按照以上的性質實現merge x,y 先選出x,y中比較大的那個 大根堆為例 再拿它的右兒子和另乙個去merge,如果merge出來不符合性質2就swap一下...