原本想要只講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.貢獻知足交換律,結合律,具備可加性
同:
1.都是按時間進行分治
2.代碼很像(不徹底同樣,這在異中會講到)
3.複雜度都是O(f(n)logn)
異:
1.總體二分有二分答案操做
2.適用範圍不一樣(具體看上面的使用條件)