左偏樹,顧名思義,是左邊的結點權值較大的樹形資料結構。主要用於兩個優先佇列的快速合併,是可並堆的一種實現方式。
定義與性質:
外結點:乙個結點的右子結點為空就為外結點
距離:結點一直向右,直到外結點所經歷的步數,每個結點距離等於右兒子的距離+1。
左偏樹的父親結點的優先順序高於兒子結點
父親結點的左子節點的距離大於等於右子節點的距離
合併操作:
大體流程:遞迴操作,將
b結點與
a結點的右孩子合併,同時會將
b結點的左右孩子合併……以此類推,然後根據實際情況維護左孩子與右孩子的位置順序
偽**:
}
插入操作:將新結點當作只有乙個根的左偏樹,merge合併。
刪除操作:直接刪除根結點,合併左右子樹。
時間限制
:1 sec
記憶體限制
:128 mb提交:
32 解決:
6[提交
][狀態
][討論版]
很久很久以前,在乙個廣闊的森林裡,住著
n只好鬥的猴子。起初,它們各幹各的,互相之間也不了解。但是這並不能避免猴子們之間的爭吵,當然,這只存在於兩個陌生猴子之間。當兩隻猴子爭論時,它們都會請自己最強壯的朋友來代表自己進行決鬥。顯然,決鬥之後,這兩隻猴子以及它們的朋友就互相了解了,這些猴子之間將再也不會發生爭論了,即使它們曾經發生過衝突。
假設每乙隻猴子都有乙個強壯值,每次決鬥後都會減少一半(比如
10會變成5,
5會變成
2.5)
。並且我們假設每只猴子都很了解自己。就是說,當它屬於所有朋友中最強壯的乙個時,它自己會站出來,走向決鬥場。
輸入分為兩部分。
第一部分,第一行有乙個整數
n(n<=100000)
,代表猴子總數。
接下來的
n行,每行乙個數表示每只猴子的強壯值
(小於等於
32768)
。第二部分,第一行有乙個整數
m(m<=100000)
,表示有
m次衝突會發生。
接下來的
m行,每行包含兩個數x和
y,代表第
x個猴子和第
y個猴子之間發生衝突。
輸出每次決鬥後在它們所有朋友中的最大強壯值。資料保證所有猴子決鬥前彼此不認識。
5
20
16
10
10
4
4
2 3
3 4
3 5
1 5
8
5
5
10
很經典的左偏樹題,每次兩隻猴子打架之後將兩隻猴子所屬的堆合併起來,並且將最強壯的猴子置於堆頂
#include#include#includeusing namespace std;
const int max=1000000;
int lch[max],rch[max],father[max],dis[max],data[max];
int n,m;
bool cmp(int a,int b)
int merge(int a,int b)
int getfather(int p)
void fight(int a,int b)
int main()
return 0;
}
可並堆之左偏樹
可並堆 mergeable heap 是一類抽象資料型別,它除了支援一般的優先佇列的基本操作以外,還支援額外的合併操作。而可並堆有多種,包括斜堆,左偏樹,二項堆,配對堆,斐波那契堆等。這裡我們只介紹左偏樹 leftist tree 它是最常用的一種可並堆。至於為什麼說最常用,我們會在後面講到。先挖個...
堆之左偏樹
左偏樹 左偏堆 優勢 兩個左偏樹合併效率高o logn 外結點 乙個結點的孩子數不滿兩個,就稱之為外結點。距離 dist 每個節點上有個距離 dist 的屬性,dist的值為該結點到最近的外結點所經過的邊的個數。外結點的dist 0。空結點的dist 1。左偏樹定義 1.是一顆二叉樹。2.是個堆。3...
左偏樹(可並堆)
左偏樹其實是一種可並堆,它可以 o log2 n o l og2n 合併兩個堆。那左偏?也就是說他左邊肯定有什麼東西比右邊大 別著急,在左偏樹上有乙個叫距離的東西 個點的距離,被定義為它子樹中離他最近的外節點到這個節點的距離 這與樹的深度不同 其中我們定義乙個節點為外節點,當且僅當這個節點的左子樹和...