cdq分治 筆記

博客觀賞效果更佳:
github
cnblogs

算法講解

這個算法用於解決三維偏序問題。

三維偏序:給定 nn 個三元組: (ai,bi,ci)(a_i,b_i,c_i),求同時滿足滿足 aiaj,bibj,cicja_i\le a_j,b_i\le b_j,c_i\le c_j(i,j)(i,j) 的數量。

那這該咋求呢⊙(・◇・)?

先把維度降下來,二維偏序,會不會做?就是求多少個 (i,j)(i,j) 滿足 aiaj,bibja_i\le a_j,b_i\le b_j

顯然,先按照 aa 排一下序。然後就變成了 i<j,bibji<j,b_i\le b_j 的問題了。可以用樹狀數組做。最典型的案例就是逆序對問題,這個都寫熟練了哈(*╹▽╹*)

三維偏序的問題,也是先按 aa 排一下序。然後接下來的問題考慮分治(這樣的分治過程被我們稱爲“cdq分治”)

假設我們要求 [l,r][l,r] 中的答案。已經求好了 [l,mid],[mid+1,r][l,mid],[mid+1,r] 中的答案,現在只需要考慮跨區的答案了。

那麼我們可以把 [l,mid][l,mid][mid+1,r][mid+1,r] 內部都按照 bb 排序。因爲我們只要考慮跨區的答案,那麼我們把兩邊分別都隨便排序,對跨區的時候 aa 的大小關係沒有影響。然後我們在 [mid+1,r][mid+1,r] 中枚舉一個元素 jj,找到在 [l,mid][l,mid] 中有多少個 ii 滿足 bibjb_i\le b_j,然後這個 ii 顯然是遞增的。然後我們一邊單調的維護這個 ii ,一邊用樹狀數組維護 cicjc_i\le c_j 的數量即可。

板子

洛谷3810 陌上花開
在這裏插入圖片描述

(↑代碼找我老婆要)(那張圖是一個鏈接(**))(偷偷測試功能)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章