題解 BZOJ4919 大根堆

2022-05-03 17:42:10 字數 1349 閱讀 7582

題面:傳送門。

老師說今天要考一道線段樹合併,然後。。。然後這道題我就gg了。(當然可以用線段樹合併寫,只是比較複雜)

有人賽時想了個貪心,然後被機房巨佬hack了,結果在hack的過程中巨佬想出了正解。。。

貪心思路:

對於乙個節點,取右邊的(大一點的)肯定更優。

(其實很好hack啊,隨便搞一條鏈就可以了)

ac思路:

對於每個節點,像lis那樣找子節點中大於它的最小的,然後替換掉,這樣肯定是最優的。

於是這道題可以看做拓展到樹上的lis,

於是我們每個節點搞乙個set,然後一路往上啟發式合併就可以了。

1 #include 2 #include 3 #include 4 

5 using namespacestd;

6 7 namespacestandardio

15 16 templateinline voidwrite (t x)

21 22 }

23 24 using namespacestandardio;

25 26 namespacesolve edge[n<<1];

37 multisets[n];

38

39 inline void add (unsigned int a,unsigned intb)

42 inline void merge (unsigned int u,unsigned intv)

46 for (register multiset::iterator i=s[v].begin(); i!=s[v].end(); ++i)

49 s[v].clear();

50 }

51 void dfs (unsigned intnow)

56 multiset::iterator place=s[now].lower_bound(val[now]);

57 if (place!=s[now].end()) s[now].erase(place);

58 s[now].insert(val[now]);

59 }

60 61 inline voidsolve()

68 dfs(1);

69 write(s[1].size());

70 }

71

72 }

73 74 using namespace solve;

75 76 intmain ()

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 大根堆 線段樹合併 二分 離散化

題目鏈結 題意 給你一棵樹,每個點有點權,問你最多能選出多少個點,使得所有選出的點中子節點的權值都比父節點小 嚴格小於 點數2e5,權值1e9 題解 首先的乙個暴力是用乙個樹形dp,dp x i dp x i dp x i 表示點x xx為根的子樹內,最大權值是i ii時子樹內最多選的點數。我們不難...