分治

LUlululu1616發表於2024-09-08

由 ryz 講解

什麼是分治?

  • 把一個較大規模的問題分成若干個較小規模的問題。
  1. 小規模的問題與原問題不同(根號分治)

  2. 小規模的問題與原問題相同(對數分治)

二分就是一種對數分治的方法。

操作序列分治

cdq 分治

修改和詢問的整體分治也被稱為 cdq 分治。

要求:修改對詢問具有可加性

主要操作:

  1. 將所有操作離線

  2. 對於區間 \([l,r]\),選取中點 \(mid\),只統計左修改對右的貢獻

  3. 遞迴 \([l, mid], [mid + 1, r]\)

無題號 函式

三種操作,加入一個一次函式,刪除一個函式,求 \(x_0\) 處所有函式的最大值,\(n\le 10^6\)

第一眼看上去是線段樹分治(),但是要求用 cdq 做。

考慮維護一個下凸殼,插入好做,刪除不好做

考慮先從左往右掃一遍統計只有 + 的貢獻

然後從 \(r\rightarrow mid+1\),把刪除改成增加,倒著掃,從 \(r\rightarrow mid + 1\),用平衡樹維護下凸殼。

  • 如何用平衡樹維護下凸殼

注意到斜率是單增的,考慮維護這個東西。

他肯定是包含了一個斜率區間,然後切掉了兩端直線的部分

那麼我們維護兩個東西:凸包上的斜率,交點的 \(x\) 座標

然後平衡樹找到斜率之後,直接向前向後列舉被刪除掉的斜率,維護這兩個東西就行

講了這麼久,最後告訴我 cdq 過不去()

正解是線段樹分治套平衡樹維護凸包(),這玩意兒是 \(O(n\log^2 n)\)

可以在節點時就把斜率排序好,再插入,用雙指標維護即可,複雜度 \(O(n\log n)\)

具體的,假設現在斜率為 \(a_1, \cdots a_n\), \(b_1, \cdots b_m\) 歸併排序一下就行

相關文章