洛谷 P3377 模板 左偏樹(可並堆)

2022-01-10 17:58:11 字數 1719 閱讀 2685

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

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

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 21 4 2

2 2

輸出 #1

1

2

【資料規模】

對於 30% 的資料:n≤10,m≤10。

對於 70% 的資料:n≤10,\(m\le 10^3\)。

對於 100% 的資料:\(n\le 10^5\),\(m\le 10^5\),初始時小根堆中的所有數都在 int 範圍內。

【樣例解釋】

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

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

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

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

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

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

故輸出依次為 1、2。

#includeusing namespace std;

const int maxn=1e5+5;

struct trrtr[maxn];

/*dis:記錄這個節點到它子樹裡面最近的葉子節點的距離,葉子節點距離為0

val:節點的權值

ls:左兒子

rs:右兒子

rt:根節點編號

*/int bing(int xx,int yy)//維護小根堆的性質

tr[xx].rs=bing(tr[xx].rs,yy);//將xx的右兒子和yy合併

if(tr[tr[xx].ls].distr[tr[xx].ls].rt=tr[tr[xx].rs].rt=tr[xx].rt=xx;//維護根節點

tr[xx].dis=tr[tr[xx].rs].dis+1;//乙個節點的距離始終等於右兒子+1

return xx;

}int get(int xx)//路徑壓縮查詢根節點

void sc(int xx)//刪除某個節點

int main()

for(int i=1;i<=m;i++) else }}

return 0;

}

洛谷P3377 模板 左偏樹(可並堆)

題目描述 如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 ...

洛谷 P3377 模板 左偏樹(可並堆)

有 n nn 個小根堆,每個堆只有乙個數,進行兩種操作 1 x y將第 x,y x,yx,y 個數分別在的小根堆合併 2 x輸出第 x xx 個數所在的的堆的最小數,並將其刪除,有多個則刪除最先輸入的,若第 x xx 個數已刪除,則輸出 1 1 1思路 左偏樹 include include def...

洛谷P3377 模板 左偏樹(可並堆)

如題,一開始有n個小根堆,每個堆包含且僅包含乙個數。接下來需要支援兩種操作 操作1 1 x y 將第x個數和第y個數所在的小根堆合併 若第x或第y個數已經被刪除或第x和第y個數在用乙個堆內,則無視此操作 操作2 2 x 輸出第x個數所在的堆最小數,並將其刪除 若第x個數已經被刪除,則輸出 1並無視刪...