資料結構 左偏樹

2021-08-18 18:29:36 字數 2775 閱讀 1199

題目描述

如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作:

操作1: 1 x y 將第x個數和第y個數所在的小根堆合併(若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作)

操作2: 2 x 輸出第x個數所在的堆最小數,並將其刪除(若第x個數已經被刪除,則輸出-1並無視刪除操作)

輸入輸出格式

輸入格式:

第一行包含兩個正整數n、m,分別表示一開始小根堆的個數和接下來操作的個數。

第二行包含n個正整數,其中第i個正整數表示第i個小根堆初始時包含且僅包含的數。

接下來m行每行2個或3個正整數,表示一條操作,格式如下:

操作1 : 1 x y

操作2 : 2 x

輸出格式:

輸出包含若干行整數,分別依次對應每乙個操作2所得的結果。

輸入輸出樣例

輸入樣例#1:

5 5

1 5 4 2 3

1 1 5

1 2 5

2 2

1 4 2

2 2輸出樣例#1:1 2

說明當堆裡有多個最小值時,優先刪除原序列的靠前的,否則會影響後續操作1導致wa。

時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=10,m<=10

對於70%的資料:n<=1000,m<=1000

對於100%的資料:n<=100000,m<=100000

樣例說明:

初始狀態下,五個小根堆分別為:、、、、。

第一次操作,將第1個數所在的小根堆與第5個數所在的小根堆合併,故變為四個小根堆:、、、。

第二次操作,將第2個數所在的小根堆與第5個數所在的小根堆合併,故變為三個小根堆:、、。

第三次操作,將第2個數所在的小根堆的最小值輸出並刪除,故輸出1,第乙個數被刪除,三個小根堆為:、、。

第四次操作,將第4個數所在的小根堆與第2個數所在的小根堆合併,故變為兩個小根堆:、。

第五次操作,將第2個數所在的小根堆的最小值輸出並刪除,故輸出2,第四個數被刪除,兩個小根堆為:、。

故輸出依次為1、2。

題解左偏樹與平衡樹的不同就在於平衡樹為了使插入、查詢等操作耗時盡可能少,所以使整個樹的深度平均,避免退化成鏈的狀況。而左偏樹的目的與此不同,為了使堆的合併盡可能快,左偏樹將右兒子離空節點的距離調整的較小以求快速合併(距離和深度不一樣,左偏並不意味著左兒子的深度或大小一定大於右兒子)。

以小根左偏樹為例,妙妙的性質如下:

1.節點的權值小於其左右兒子的權值    

堆的性質,顯然滿足。

2.節點左兒子離空白節點的距離不小於右兒子離空白節點的距離

為了使合併盡可能快,需要這個性質。

3.節點離空白節點的距離等於右兒子的距離加1

也是特殊性質,供快速合併用。

4.節點的最大距離為lo

gn+1

2−1 log

2n+1

−1人家可是一棵樹呢,雖然有點歪。

1.合併

我們假設左邊的為被插入樹,右邊的為插入樹(畢竟博主右撇子)。

首先,我們要保證a的權值小於b(不然就交換),然後,接下來我們就需要合併a的右兒子和b了。

每次我們都重複上述操作,構成乙個遞迴,直到被插入樹沒有右兒子時,就可以插入了。合併完畢後,a右兒子離空節點的距離可能大於左兒子,破壞了性質2,這時我們只需交換左右兒子即可。最後,因為a右兒子的距離可能會變,我們需要更新距離。

盜乙個**:

2.插入

實質上是合併乙個點與一棵樹,模擬上面的操作。

3.刪除

將要刪除的節點拉出來,將其左右兒子合併即可。

4.查詢根節點

記錄個爸爸節點往上跳就好了。

**

#include

#define ls tree[x].son[0]

#define rs tree[x].son[1]

using

namespace

std;

const

int m=100005;

struct node;

node tree[m];

bool del[m];

int n,m;

void in()

int merge(int x,int y)

int pop(int x)

int root(int x)

void ac()

else

a=root(a);

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

pop(a);

del[a]=1;}}

}int main()

資料結構 左偏樹

今天學了左偏樹,看了一天,一些細節還是不太明白。有點混亂。做題的時候也不是很明白方法。先來介紹左偏樹 見 資料結構 9 左偏樹 見例題 判斷是否認識,並查集。因為要用到合併,而且輸出最強壯值,二叉堆不能合併,所有要用到能夠合併的資料結構 左偏樹。這題能夠好好理解左偏樹的實現方法。include in...

高階資料結構 左偏樹

我們曾經學習過基礎資料結構之一 堆 heap 堆支援三種操作 以小根堆為例 1 查詢 query 查詢堆中最小的元素 2 刪除 del 刪除堆中的任意乙個元素 3 插入 insert 插入乙個新元素 4 維護 modify 維護堆的性質 任何非葉子結點的權值都大於它的所有子結點。在刪除和插入後進行維...

資料結構入門7 左偏樹

一種可並堆,具有左偏性質。每個點有乙個距離。距離則是如下定義的 節點i稱為外節點 externalnode 當且僅當節點i的左子樹或右子樹為空 left i null或right i null 節點i的距離 dist i 是節點i到它的後代中,最近的外節點所經過的邊數。特別的,如果節點i本身是外節點...