CDQ分治與總體二分

前言


 

原本想要只講CDQ分治的,但因爲總體二分和CDQ分治有一些類似之處,便順藤摸瓜一塊兒講了算法

在講解以前,先普及一下在線算法和離線算法的定義數組

在線算法: 能夠以序列化的方式一個一個的處理輸入,沒必要事先知道全部輸入數據 網絡

離線算法: 必須事先知道全部的輸入數據 (例如選擇排序就是一個離線算法,而插入排序則不是)數據結構

還有一點,在學習算法前掌握凸殼和斜率優化可能會有神助學習

 

 

CDQ分治


 

CDQ分治,是一種十分優美的暴力算法。它能夠代替不少比較玄學的數據結構,乃廣大OIer的福音優化

可是,不得不感嘆一句,網絡上關於CDQ分治的講解實在是太少,並且語言過於抽象,spa

這致使不少OIer沒能接觸到其魅力就避而遠之。排序

CDQ分治的關鍵在於,每一個子問題不只是解決它自身,而且用前一個子問題來求解後一個子問題。經常使用來將一些動態的問題轉化到靜態來解決,使問題處理起來更加方便。 
使用CDQ分治須要知足必定的條件:遞歸

1.題目容許離線操做io

2.修改操做對詢問的貢獻獨立,且修改之間互不影響

3.修改對答案的貢獻是肯定的,與斷定標準無關

4.常數小

揭開這個幌子,先來舉例說明這個算法的特色

1.代碼簡短(比起樹套樹來講)

2.易想出

3.爲離線算法(化動態開點爲靜態查詢),若是須要強制在線的話仍是推薦其它算法

和普通的分治同樣,分和治在這個算法中都獲得了很好的展示

1.咱們要解決一系列問題,這些問題通常包含修改和查詢操做,能夠把這些問題排成一個序列,用一個區間[L,R]表示。

2.分。遞歸處理左邊區間[L,M]和右邊區間[M+1,R]的問題。

3.治。合併兩個子問題,同時考慮到[L,M]內的修改對[M+1,R]內的查詢產生的影響。即,用左邊的子問題幫助解決右邊的子問題。

 

和不少數據結構(線段樹,樹狀數組。。。)同樣,它作了這麼可能是爲了什麼?就是爲了把符合本次查詢的限制的修改對答案產生的效果合併起來 

 

 

 總體二分


 

說完了CDQ分治再來講說總體二分

相對於CDQ分治,總體二分的知名度會更高一些,是不少OIer在解決一些問題時的經常使用方法

總體二分產生的緣由:對於單個查詢而言,咱們能夠採用預處理+二分答案的方法解決,但每每咱們要回答的是一系列的查詢,對於每一個查詢而言咱們都要從新預處理而後二分,時間複雜度沒法承受,可是咱們仍然但願經過二分答案的思想來解決,總體二分就是基於這樣一種想法——咱們將全部操做(包括修改和查詢)一塊兒二分,進行分治 

簡單地說,總體二分就是對詢問和答案同時二分

一樣的,總體二分也須要知足必定的條件:

1. 題目容許離線操做 

2. 修改操做對詢問的貢獻獨立,且修改之間互不影響 

3. 修改對答案的貢獻是肯定的,與斷定標準無關 

4. 答案具備二分性

5.貢獻知足交換律,結合律,具備可加性

 

 CDQ分治和總體二分的異同


 

同:

1.都是按時間進行分治

2.代碼很像(不徹底同樣,這在異中會講到)

3.複雜度都是O(f(n)logn)

異:

1.總體二分有二分答案操做

2.適用範圍不一樣(具體看上面的使用條件)

相關文章
相關標籤/搜索