資料結構 配對堆

2021-08-21 19:13:46 字數 1694 閱讀 7199

題目描述

如題,初始小根堆為空,我們需要支援以下3種操作:

操作1: 1 x 表示將x插入到堆中

操作2: 2 輸出該小根堆內的最小數

操作3: 3 刪除該小根堆內的最小數

輸入輸出格式

輸入格式:

第一行包含乙個整數n,表示操作的個數

接下來n行,每行包含1個或2個正整數,表示三種操作,格式如下:

操作1: 1 x

操作2: 2

操作3: 3

輸出格式:

包含若干行正整數,每行依次對應乙個操作2的結果。

輸入輸出樣例

輸入樣例#1:

5 1 2

1 5

2 3

2輸出樣例#1:2 5

說明時空限制:1000ms,128m

資料規模:

對於30%的資料:n<=15

對於70%的資料:n<=10000

對於100%的資料:n<=1000000(注意是6個0。。。不過不要害怕,經過編者實測,堆是可以ac的)

樣例說明:

故輸出為2、5

題解託某位毒瘤張瀚文老師的福,學習了一大堆堆知識。

配對堆不像其他嬌氣的堆,它對堆本身的形態沒有什麼要求,只要是棵樹就行了,插入/合併也很任性,直接比較兩個根的大小,優先順序高的當爸爸,輕鬆o(

1)o (1

)完成插入/合併。

配對堆還可以支援改變堆中元素的值,只需要將元素原來的父邊斷掉,修改完權值後直接與根合併就完了,雖然看起來是o(

1)o (1

)的,但是因為會影響到po

p pop

操作,所以均攤下來複雜度為o(

log2

n)o (l

og2n

)。因為前面的操作比較隨意,所以po

p pop

操作要收拾隨意連邊的爛攤子,我們要把根節點的所有兒子不停地兩兩合併合成一棵樹,複雜度是o(

兒子個數

) o(兒

子個數)

的,但是神奇攤還分析說,它是o(

log2

n)o (l

og2n

)的,它就是o(

log2

n)o (l

og2n

)的。**賊好寫,甚至短於左偏樹。

#include

using

namespace

std;

const

int m=2e6+5;

int n,root,id,tot,top,val[m],head[m],nxt[m],to[m],dad[m];

queue

dui;

void add(int x,int y)

int _new(int x)

int merge(int x,int y)else }

void pop()

if(dui.size())root=dui.front(),dui.pop();

else root=0;

}void in()

void ac()

}int main()

配對堆 資料結構說解

乙個配對堆是一棵滿足堆序性質的樹,樹上每個節點儲存其關鍵字 子節點指標 兄弟節點指標和前驅指標。當該節點為其父節點的第乙個兒子,即父節點的子節點指標指向該節點時,該節點的前驅指標指向其父節點 否則該節點的前驅指標指向該節點的前乙個兄弟,即該節點的前驅指標指向的節點的兄弟節點指標指向該節點。配對堆可以...

資料結構 堆

最大堆 最小堆 堆的定義是 n個元素的序列,當且僅當滿足如下關係時被成為堆 1 ki k2i 且 ki k2i 1 或 2 ki k2i 且 ki k2i 1 i 1,2,n 2 當滿足 1 時,為最小堆,當滿足 2 時,為最大堆。若將此序列對應的一維陣列堪稱是乙個完全二叉樹,則2i和2i 1個節點...

資料結構 堆

資料結構 堆的操作和實現 當應用優先順序佇列或者進行堆排序時,一般利用堆來實現。堆是乙個完全 除最底層 外都是滿的 二叉樹,並滿足如下條件 1 根結點若有子樹,則子樹一定也是堆。2 根結點一定大於 或小於 子結點。因為要求堆必須是完全二叉樹,所以可以用線性的資料結構,比如陣列,來實現堆。利用陣列實現...