BZOJ 4919 樹上LIS 啟發式合併

2022-03-29 10:38:01 字數 874 閱讀 1169

給定一棵n個節點的有根樹,編號依次為1到n,其中1號點為根節點。每個點有乙個權值v_i。

你需要將這棵樹轉化成乙個大根堆。確切地說,你需要選擇盡可能多的節點,滿足大根堆的性質:對於任意兩個點i,j,如果i在樹上是j的祖先,那麼v_i>v_j。

請計算可選的最多的點數,注意這些點不必形成這棵樹的乙個連通子樹。

由於點不需要相鄰,此題其實是樹上的lis,從葉子節點向根節點形成lis

考慮lis的\(o(nlogn)\)演算法中用到的陣列,用multiset對每個節點維護這樣乙個陣列,儲存子樹內的值

向上的同時合併兩個multiset,用啟發式合併

時間複雜度應該是\(o(nlog^2n)\)

#include#include#include#include#define maxn 200005

using namespace std;

int n;

struct edgee[maxn<<1];

int head[maxn];

int sz;

void add_edge(int u,int v)

int a[maxn];

multisets[maxn];

void merge(int x,int y)

}void dfs(int x,int fa)

} multiset::iterator it=s[x].lower_bound(a[x]);

if(it==s[x].end()) s[x].insert(a[x]);

else

}int main()

} dfs(1,0);

printf("%d\n",s[1].size());

}

BZOJ4919 大根堆 樹上LIS

題目描述見鏈結 樹上 lis lisli s 問題,使用std multisetst維護當前子樹內所有可能的 lis lisli s 結尾,從前往後 lis lisli s結尾 對應的長度遞增 子樹之間互不影響,只需考慮子樹根節點 u uu 對子樹內的影響,模擬 序列lis lisli s 的做法,...

bzoj 4919 大根堆(set啟發式合併)

傳送門biu 假設是在序列上,就變成了nlogn的dp求最長上公升子串行問題 假設是在樹上,我們只需要在每個節點存下dp陣列,然後用set的啟發式合併將dp陣列合併就可以了 代替splay include define n 200005 using namespace std vector e n ...

題解 BZOJ4919 大根堆

題面 傳送門。老師說今天要考一道線段樹合併,然後。然後這道題我就gg了。當然可以用線段樹合併寫,只是比較複雜 有人賽時想了個貪心,然後被機房巨佬hack了,結果在hack的過程中巨佬想出了正解。貪心思路 對於乙個節點,取右邊的 大一點的 肯定更優。其實很好hack啊,隨便搞一條鏈就可以了 ac思路 ...