部落格觀賞效果更佳:
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 座標,每次讀...