題面:傳送門。
老師說今天要考一道線段樹合併,然後。。。然後這道題我就gg了。(當然可以用線段樹合併寫,只是比較複雜)
有人賽時想了個貪心,然後被機房巨佬hack了,結果在hack的過程中巨佬想出了正解。。。
貪心思路:
對於乙個節點,取右邊的(大一點的)肯定更優。
(其實很好hack啊,隨便搞一條鏈就可以了)
ac思路:
對於每個節點,像lis那樣找子節點中大於它的最小的,然後替換掉,這樣肯定是最優的。
於是這道題可以看做拓展到樹上的lis,
於是我們每個節點搞乙個set,然後一路往上啟發式合併就可以了。
1 #include 2 #include 3 #include 45 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時子樹內最多選的點數。我們不難...