luoguP3377 模板 左偏樹(可並堆)

2021-08-13 09:15:20 字數 1613 閱讀 7049

題目描述

如題,一開始有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

今天luogu不知道為什麼炸了

//這裡寫**片

#include

#include

#include

using

namespace

std;

const

int n=100010;

int fa[n],val[n],n,m,ch[n][2],dis[n];

bool p[n];

int find(int x)

int merge(int x,int y)

int main()

int opt,x,y;

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

else

p[now]=1;

printf("%d\n",val[now]);

fa[now]=merge(ch[now][0],ch[now][1]);

fa[fa[now]]=fa[now];}}

return

0;}

luogu P3377 左偏樹(可並堆)

傳送門 左偏樹 左偏!也就是下面這種左邊大,右邊小的樹 可並堆 可以合併的堆 堆 維護最值的資料結構 核心 細節 先來 int merge int x,int y 在合併時,往右子樹走,當發現右邊的值不合法時,則另另乙個堆的值來swap 以最大值為例 當發現x每次合併完之後更新高度 乙個節點的高度 ...

P3377 左偏樹,模板)

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

洛谷 P3377 模板 左偏樹

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