發表文章

目前顯示的是有「可合併堆」標籤的文章

[TIOJ] 1429. [APIO '12] 忍者調度問題

題目連結: http://tioj.infor.org/problems/1429 本題其實有很多種寫法,例如:樹剖、整體二分搜、堆(啟發式合併或可合併),我這裡的做法是用可合併堆的做法,也是裡面最快的一種(?,可以發現對於某個節點,如果已知他所有小孩的選法,那就把那些節點全部混在一起,然後如果超過預算就把最大的移掉,而因為要找最大的,我們需要用到heap,不過我們還需要快速合併多個堆,所以可以採用可合併堆,或是直接啟發式合併就好。 我在這裡採用的可合併堆是配對堆,雖然大家都寫左偏樹,不過我覺得配對堆比較好寫XDD,一種似乎均攤複雜度接近費波那契堆的東東,詳細證明可以看他的 論文 ,不過我也不是很熟,簡單說一下他的做法:合併跟插入都是直接跟根比大小後決定誰當根,所以有可能一個根下面有一堆小孩,為了解決會因此爛掉的狀況,於使我們在pop的時候讓他的小孩們緊縮一點(?,就是pop時就把他的小孩兩兩合併,直到剩一個為止。似乎跟splay tree有點類似,大概這樣吧 註:這裡採用的合併方式因為有點懶人,根據論文他只能證出$O(\frac{log n log log n}{ log log log n})$的上界,不過$ \frac{ \frac{log n log log n}{ log log log n} }{log n}$在$n #include <bits/stdc++.h> using namespace std; #define PB push_back typedef long long lld; #define N 100000 struct pairingNode{ int val; vector<pairingNode*> child; }; class pairingHeap{ private: pairingNode* root; int count; public: lld sum=0; pairingHeap(){root=NULL;count=0;} ...