P5290 十二省聯考2019 春節十二響

2022-05-19 11:29:04 字數 1205 閱讀 7934

傳送門

考慮乙個子樹裡是怎麼劃分的,維護劃分出來的每個集合的最大值,這個可以用乙個 $multiset$ 維護

設 $s[x]$ 表示節點 $x$ 的子樹中,最優劃分 劃分出來的每個塊的節點最大值

首先葉子節點的集合顯然只有它本身

然後考慮子樹之間的合併,設兩個子樹根節點為 $x,y$,因為兩個子樹之間一定不會有祖先後代關係

貪心地想,顯然 $s[x]$ 的最大值優先跟 $s[y]$ 的最大值合併(取 $max$),然後次大值跟次大值合併...這樣一路合併下去是最優的

所以直接啟發式合併就好了

$x$ 的子樹合併完後還要考慮當前節點 $x$ 也加入進來,顯然此節點只能單獨分乙個塊出來

一開始以為複雜度 $o(nlog^2_n)$(啟發式合併 $nlog_n$,$multiset$ 單次操作 $log_n$)

但是經過對**的分析可以發現,這並不是直接合併,而是小的 $s$ 和大的取乙個最大值後就沒了,並沒有增加大的集合的集合大小

所以每個節點只會算一次,複雜度 $o(nlog_n)$

#include#include

#include

#include

#include

#include

using

namespace

std;

typedef

long

long

ll;inline

intread()

returnx;}

const

int n=4e5+7

;int fir[n],from[n<<1],to[n<<1

],cntt;

inline

void add(int a,int

b)int

n,val[n];

multiset

s[n];

multiset

::iterator it,pit,itt;

inline

void merge(int x,int y)//

很多細節的啟發式合併操作

if((*it)>(*pit)) s[x].erase(pit),s[x].insert(*it);//

注意最後s[y].begin()的值還沒合併

}void dfs(int

x)int

main()

P5290 十二省聯考2019 春節十二響

考試的時候,本來想拿60的貪心,但是只拿了15 很不開心!不過現在知道正解了qwq 對於每個點,都開乙個優先佇列,這個優先佇列裡的值,代表這個點的子樹分成的若干個集合中最大的值。那麼我們對於乙個沒有處理的點,分別列舉每乙個子樹,分別合併每乙個優先佇列,最後再加入這個點,得到新的優先佇列。對於正確性,...

洛谷P5290 春節十二響

傳送門 qaqqaq 題意 給你一棵樹,每個點有權值,把樹上 n 個點分成若干個集合,每個集合中的元素兩兩之間不存在祖先關係,使得每個集合中的最大值之和最小 思路 觀察部分分,我們會發現有乙個 鏈 的樣例。我們看鏈的思路 1為頂點,那麼1兩端就是兩條鏈,每個集合中每條鏈只能包含1個元素,然後1頂點單...

十二省聯考2019 遊記

在機房呆了一天,大概看了看原先寫過的題,有點頹。下午的時候和大家一起打掃了一下機房。走的時候,看著空無一字的黑板,風吹起的棕黃色窗簾,遠方的藍色天空,有一種很濃厚的哀傷。時間過得真快啊,轉眼就是省選了呢。許是要退役了吧?許是要退役了吧。下午去試機了,感覺鍵盤不太星啊。考場倒是換了乙個地方 但是不讓我...