cdq分治 筆記

2021-10-05 16:52:50 字數 1741 閱讀 5618

部落格觀賞效果更佳:

github

cnblogs

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

三維偏序:給定 n

nn 個三元組: (ai

,bi,

ci)(a_i,b_i,c_i)

(ai​,b

i​,c

i​),求同時滿足滿足 ai≤

aj,b

i≤bj

,ci≤

cja_i\le a_j,b_i\le b_j,c_i\le c_j

ai​≤aj

​,bi

​≤bj

​,ci

​≤cj

​ 的 (i,

j)(i,j)

(i,j

) 的數量。

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

先把維度降下來,二維偏序,會不會做?就是求多少個 (i,

j)(i,j)

(i,j

) 滿足 ai≤

aj,b

i≤bj

a_i\le a_j,b_i\le b_j

ai​≤aj

​,bi

​≤bj

​。顯然,先按照 a

aa 排一下序。然後就變成了 i

bi≤b

jiibi​≤

bj​ 的問題了。可以用樹狀陣列做。最典型的案例就是逆序對問題,這個都寫熟練了哈(*╹▽╹*)

三維偏序的問題,也是先按 a

aa 排一下序。然後接下來的問題考慮分治(這樣的分治過程被我們稱為「cdq分治」)

假設我們要求 [l,

r][l,r]

[l,r

] 中的答案。已經求好了 [l,

mid]

,[mi

d+1,

r][l,mid],[mid+1,r]

[l,mid

],[m

id+1

,r] 中的答案,現在只需要考慮跨區的答案了。

那麼我們可以把 [l,

mid]

[l,mid]

[l,mid

] 和 [mi

d+1,

r][mid+1,r]

[mid+1

,r] 內部都按照 b

bb 排序。因為我們只要考慮跨區的答案,那麼我們把兩邊分別都隨便排序,對跨區的時候 a

aa 的大小關係沒有影響。然後我們在 [mi

d+1,

r][mid+1,r]

[mid+1

,r] 中列舉乙個元素 j

jj,找到在 [l,

mid]

[l,mid]

[l,mid

] 中有多少個 i

ii 滿足 bi≤

bjb_i\le b_j

bi​≤bj

​,然後這個 i

ii 顯然是遞增的。然後我們一邊單調的維護這個 i

ii ,一邊用樹狀陣列維護 ci≤

cjc_i\le c_j

ci​≤cj

​ 的數量即可。

洛谷3810 陌上花開

(↑**找我老婆要)(那張圖是乙個鏈結(*▽*))(偷偷測試功能)

學習筆記 CDQ分治

分治,考慮前一半對後一半的影響。和一般分治不太相同的思想是,一般分治不分誰對誰的影響,跨mid的都要統計。全域性變數統計 而cdq貌似要落腳到前一半對後一半的影響上,也就是貢獻在後一半統計,由前一半產生。大概使用情況 1.三維偏序 2.優化dp 3.這個裡面有。注意處理三維情況的巧妙性。heoi20...

學習筆記 CDQ分治

聽娜姐講完fft,一臉懵逼,還是來講講 cdq分治 吧。解決 帶時間軸的更改和查詢 問題。首先我們要知道,這個演算法是離線的,還是利用遞迴進行求解的。把讀入的n個操作都按照時間軸排列好。把時間軸劈開,分為 l,mid 和 mid 1,r 兩部分。開始當前層cdq l,r 的求解前先進行cdq l,m...

CDQ分治筆記 例題

看這樣乙個問題 在乙個三維座標系中,有若干個點,每個點都有對應的座標 x i y i z i 我們要對於每個點求所有滿足 x j x i,y j y i z j z i 的 j 的數量。考慮在二維平面上怎麼做 我們可以將所有點按照 x 座標排序,再用乙個樹狀陣列或者其他資料結構維護 y 座標,每次讀...