cdq分治小結
cdq分治,同機房的大佬看了好幾天了,窩這種蒟蒻也來湊個熱鬧(qaq)
引用大佬的話:
二維裡面 :最簡單的簡化版就是逆序對問題了,,可以用樹狀陣列來維護,說他是簡化版其實是因為有一維:下標已經有序了,那麼就去大力♂搞
另一維就好了
公升級版:一般的二維偏序問題:思路是一樣的,要通過排序使一維有序,剩下就變成比較抽象的逆序對問題了
洛谷p1908逆序對
#includeusingnamespace
std;
int n,cnt=0,t[500010]=;
struct
noda[
500010
];long
long ans=0
;inline
intread()
int lowbit(int
x)void ad(int x,inty)}
int sum(int
x)
return
re;}
bool cmp(nod x,nod y)
bool comp(nod x,nod y)
intmain()
//先進行離散化,不然在洛谷的大力資料下過不去
sort(a+1,a+n+1,comp);//
保證一維有序
for(int i=1;i<=n;i++)
cout
return0;
}
然後才是今天的重點:::
cdq分治!!!(話說這種演算法我曾經也yy過一部分)
cdq分治其實主要是一種化繁為簡的思想,把三維偏序問題轉換為二維偏序問題
核心還是應用了二分的思想
先通過排序保證一維有序
這樣的 化 話,在二分的過程中,就可以保證其中有一維是保證遞增,對問題是沒有影響的
說人話就是沒有這一維的逆序了
這樣就在二分的時候就完全不需要考慮了呢!!!
每次在二分的時候別忘記考慮左邊的區間對右邊的影響呢
在二分後,保證與之前有序的維度不同的一維有序就行(因為之前在有序的情況下二分的,所以左邊的無論咋排序都大不過右邊的)(不用證的吧)
於是在計算左區間對右區間的逆序對時候,就算它被打亂了也沒有任何影響
然後用兩個指標分別指向兩個區間的開頭,此時只比較兩個區間後排序的那一維(如果早就有序的是x的話,那麼它就是第y維->我本來懶得設名字來著,發現自己實在是說不明白了)
大概就是不管x了,因為x在左右區間計算貢獻沒有任何貢獻
然後兩個區間對y排序,左指標設為i,右指標設為j ,若 yj <= yi 說明在y這一維度上,存在逆序關係,不過還不敢能保證在z這個之前絲毫沒管的維度上有啥子影響
所以我們就大力把z[j]加入樹狀陣列,然後查詢樹狀陣列中有多少數小於z[i]
然後剩下一維用類似歸併排序時候樹狀陣列維護就行了
對辣別忘了清空樹狀陣列偶
(要是我太辣雞說的不清楚看戴馬好了)
(這道模板題要求說小於等於,於是我們只能亂算一下了,在求完小於的情況下搞一下等於)
#includeusingnamespace
std;
inline
intread()
while(ch>='
0'&&ch<='
9')
return x*f;
}int n,_n,k,cnt[100010
];struct
node
a[100010],b[100010
];bool
cmpx(node _,node __)
return _.x<__.x;
}bool
cmpy(node _,node __)
struct
szsz
void add(int x,int k)
int ask(int x)
}t;void cdqaq(int l,int
r) a[i].ans+=t.ask(a[i].z);
++i;
}for(i=l; i)
}int
main()
}cdqaq(
1,_n);
for(int i=1; i<=_n; i++)
for(int i=0; i)
}
好辣!就是這樣!有問題千萬告訴我鴨!q:1154322610
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...
cdq分治學習筆記
0xff 學習cdq分治的前置知識 分治 歸併排序 分治 分治,字面上的解釋是 分而治之 就是把乙個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題 直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。度娘 歸併排序 歸併排序是普通分治的一種基本應用。將排序序列分...