學習筆記 CDQ分治

2022-05-31 08:54:07 字數 2365 閱讀 9322

聽娜姐講完fft,一臉懵逼,還是來講講【cdq分治】吧。。。

解決「帶時間軸的更改和查詢」問題。

首先我們要知道,這個演算法是離線的,還是利用遞迴進行求解的。

把讀入的n個操作都按照時間軸排列好。

把時間軸劈開,分為[l,mid]和[mid+1,r]兩部分。

開始當前層cdq(l,r)的求解前先進行cdq(l,mid)與cdq(mid+1,r)的求解。

拎出區間[l,mid]內的所有修改操作和區間[mid+1,r]內的所有查詢操作[mid+1,r]。

統計區間[l,mid]內的所有修改操作對區間[mid+1,r]內的所有查詢操作的影響,並將影響加入ans陣列中。

為什麼這麼做會是對的呢?我們不妨舉個例子來看看。

加入一共有7個時刻(或者說是個7操作),對於位於3時刻的修改操作,在cdq(1,7)中,統計了它對於區間[5,7]中查詢的影響,又在cdq(3,4)中統計了區間[4,4]中查詢的影響。

可以看到,對於位於3時刻的查詢操作,在我們的cdq過程中,統計了它對於[4,7]的時刻中,所有查詢操作的影響。

boi 2007 【mokia 摩基亞】     洛谷裡有,p4390。

(至於為什麼是概述呢?——題目b話太tm多了!!!

給你乙個二維平面直角座標系,還有一些操作。

操作有兩種:

1.格式"(1,x,y,w)",表示在(x,y)的地方加上權值w。

2.格式"(2,sx,sy,ex,ey)",表示詢問以(sx,sy)為左上角頂點,(ex,ey)為右下角頂點,詢問矩形區間內的權值和。

後面的修改操作不會對前面的查詢操作產生影響。

資料:運算元<=200000,x,y,sx,sy,ex,ey<=2000000

大家還是先打消要用二維樹狀陣列的念頭吧

是二維的,那麼我們應該怎麼做呢?(先提示下吧,log2的,大家可以先想一想)

滴,滴,滴,滴————————

好,時間到,那就再給大家乙個提示吧。

某名niro**的dalao(他/她 真的是dalao)說過:「cdq分治就是花log n的時間,把所有的修改操作都移到查詢操作之前。」

再想想。。。。。。

(假如說還沒有想到的話,可以先看一下下文中那些大號加粗的字,看看有沒有思路啥的)

(想到了的話,就可以把這篇部落格關掉了,再順手點個推薦啥的)

嗯,現在就到我講了吧!

二維的,又不能用二維樹狀陣列,再看看部落格標題——「cdq分治」。

en~~~~~

那就肯定是cdq分治啦!!!

那麼當我們把所有的修改都放在查詢後面之後,我們應該怎麼做呢?

顯然要對問題進行「降維打擊」

這個降維打擊是個啥呢?——就是把1、2操作(其中把2操作變成起始和結束的兩個點)對於x軸進行排序嘛。

排序之後,我們就可以保證在x軸上,前面做過的修改操作,在x軸上是永遠包含於後面的查詢操作的(如果它的x座標大於當前查詢操作右端點對應的左端點的)。

那麼我們只要維護y軸就可以了,這個可以用樹狀陣列來維護。

具體方法的話就是,給樹狀陣列中修改點的y座標加上它的權值,然後遇到查詢操作的右端點時,就統計一下y取值範圍內的和就可以了。

那麼最後的乙個問題就是如果修改點的x座標小於查詢當前查詢操作右端點對應的左端點我們應該怎麼辦呢?

大家先思考一下吧。

......

~~~好了嗎?我說嘍。——差分嘛!

具體方法就是——遇到左端點時,先把當前樹狀陣列中屬於詢問範圍的y的區間和給減掉嘛。

#includeusing

namespace

std;

const

int n=200005

;struct

point;

point a[n],b[n

<<1

];int x[n],y[n],sx[n],sy[n],ex[n],ey[n],w[n],ans[n],c[2000005

],acnt,bcnt,tot,opt;

bool

cmp (point a,point b)

void update(int x,int

val)

int query(int

x)void cdq(int l,int

r)int

main()

cdq(

1,tot);

for (int i=1;i<=tot;i++)

if (sx[i]>0) printf("

%d\n

",ans[i]);

return0;

}

學習筆記 CDQ分治

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

CDQ分治學習筆記

今天學了一下cdq分治,感覺這東西真的挺好用的,趕緊寫點東西怕以後再忘咯 其實類似於cdq分治的東西在oi早期學排序的時候就應該學過,那就是歸併排序 歸併排序的原理和cdq分治大體一樣,先劃分成兩個區間,遞迴解決兩邊,再合併起來 並且用歸併排序求逆序對的時候本質上就是在解決乙個二維偏序的問題 首先回...

CDQ分治 學習筆記

對於每個 查詢 操作,其結果ans i 1,i 1 ans i 1,i 1 ans i 1,i 1 中所有修改對其造成影響的疊加 這裡的 疊加 需要能夠比較方便的維護,例如sum min max sum min max sum mi n ma x等 定義s ol ve l r solve l,r s...