CF2018E2 Solution

spdarkle發表於2024-10-03

CF2018E2 Solution

先考慮E1的做法。

首先我們如果欽定一組 \(k\) 條線段的話,容易求出最大組數。

簡單來講就是將所有端點按照右端點排序,這樣只需要考慮一個偏序,然後掃描,將區間 \([l_i,r_i]\) 加一,當發現某個點的值為 \(k\) 時,就說明分成了一組方案。

此時我們一定清空,然後記錄當前的 \(r\),也就是後面選的點左端點不得小於等於 \(r\)

直覺上,這樣貪心選擇一定更優。設這樣的答案為 \(k\)

我們的答案可以表示為 \(\max k·f(k)\)

而我們發現,對於一個固定的 \(f(k)\),它是隨著 \(k\) 單調不升的,這很顯然。

所以對於一個固定的 \(f(k)\),可以透過二分的形式得到 \(\max k\),這樣就足以在 \(O(n\log n\sqrt{n\log n})\) 解決問題,足以透過 E1。

事實上在這裡可以透過整體二分求得所有的 \(f(k)\),它的複雜度足以降至 \(O(n^{1.5}\log n)\),這是因為在第 \(d\) 層時,值域被劃分為了 \(O(\frac{n}{2^d})\) 長的 \(2^d\) 段,在 \([\frac{n}{2^{d/2}},n]\) 範圍內 \(f\le 2^{d/2}\),而 \([1,\frac{n}{2^{d/2}}]\) 又僅有 \(O(2^{d/2})\) 段,所以這裡總段數是 \(O(2^{d/2})\) 的,總的整體二分複雜度就是 \(O(\sum^{\log_2n} 2^{d/2})=O(\sqrt n)\) 的。

那麼考慮最佳化線段樹這個過程,一個很重要的技巧是,我們只關心全域性最大值,以及字尾加

那麼可以使用並查集,維護字尾最大值出現位置

首先,我們使端點互不相同,具體地,將原本的所有端點排序(如果是相同值,原本為右端點的放在後面),然後依次給其賦值 \(1\sim 2n\)

這顯然不會破壞相交關係也不會新增。

然後我們利用並查集維護差分,每次字尾加只會造成新的 \(r\) 成為一個字尾最大值,以及增加的最大的 \(< l\) 的字尾最大值端點刪去。

利用並查集維護這個即可。

相關文章