分塊演算法顧名思義,就是將乙個序列分成若干個部分(塊)來解決
線段樹也可以解決分塊的問題,但這裡只介紹分塊演算法
說是分塊,那麼一共要分幾塊呢?
據機房dalao說,分成sqrt(n)為每塊長度
這樣一來,假設有n個元素的序列,就有 ceil(n/sqrt(n)) 塊
核心的資料結構:
struct block;
vectorblo;
vectornum;//num[i]:第i個元素所處的塊的編號 比如說 123 456 789(n=9) num[3]=1,num[5]=2
其核心思想就是先解決外部不整塊的部分,然後解決中間成塊的部分
即
這裡紅色斜線部分是多餘部分,這裡我們就需要暴力解決
即:從l到block[l].r暴力
從r到block[r].l暴力
純紅色部分就可以當做乙個整體來解決
具體方式還是要依據實際題目來設計演算法
設計函式:
這裡我們一共包含三個函式:分、查、更新
void build() //分,即分塊函式
這個函式的內容是:
1.確定對於當前序列長度為n,一共要分幾塊
2.確定下來每一塊的距離
3.給每乙個塊確定左端點和右端點
4.對於每乙個序列中的元素,確定下來i是屬於第幾塊
注意,這裡還要處理末尾的塊,因為不一定n都可以被開方
處理方法:左端點的設定與之前一樣,但是把右端點設定為n就ok了
void updata() //更新,即在區間內加上或減去乙個數c
1.處理左右兩邊的資料,暴力加上或減去c
2.處理中間成塊的資料:
for(int i=l2;i<=r2;i++)//這裡的l2和r2是成塊的左端和右端點
void find() //查,及查詢資料,也有int型的,這個據題目來設計
步驟和上面的一樣
第i個塊的左端點:(i-1)sqrt(n)+1
第i個塊的右端點:isqrt(n)
注:最後一塊的右端點=n
第i個點處於第幾個塊當中:(i-1)/sqrt(n)+1
1.rmq
當沒有要求修改值的時候:
解決步驟:
1.儲存記錄每乙個塊的最值(在輸入做預處理的時候就可以做了)
2.比較每乙個塊的最值,求出ans_max,ans_min(時間複雜度:o(n+sqrt(n) )
要求修改值的時候:
修改點的值(按照上面「解決問題」中更新函式)
按照靜態rmq來處理 時間複雜度( o(sqrt(n)) )
2.區間
1.區間求和(新增乙個sum的資料域,表示這個塊的和)
2.區間染色(新增color域,表示顏色)
有關的題目可以按照演算法標籤搜尋,或是找線段樹的題目用分塊來做
這是本蒟蒻的第一篇blog,為今年提高組做賽前整理,望dalao指點提攜!!!
分塊演算法總結(持續更新ing)
最近學了一些分塊,來總結一下個人感受 分塊是什麼呢?就是把乙個大塊拆成若干個小塊進行計算,每個小塊有可能有一些共同特點,或者每個小塊內部是有順序的,這樣,在修改操作的時候,只需要算出兩邊的節點所屬的小塊的編號分別是什麼,然後兩邊的散塊 姑且這麼叫 可以進行暴力修改,而中間的由於題目不同,可以進行不同...
查詢演算法 分塊演算法
查詢演算法 分塊演算法 查詢演算法主要有三種 線性查詢 二分查詢 分塊查詢 線性查詢效率最慢,可對無序列表進行查詢 二分查詢效率最快,只能針對有序列表進行查詢 分塊查詢的思路 分塊查詢中,每個塊中元素不一定有序的,塊間是有序的。分塊又稱索引順序查詢,這是順序查詢的一種改進方法,用於在分塊有序表中進行...
分塊演算法詳解
分塊演算法 1.思想 如果我們需要對乙個特定的序列進行操作,那麼非常直觀 簡單的方法就是純暴力 不,那叫模擬 不過如果暴力能過的話,那就呵呵了。所以我們要想一些比較高能的資料結構 分塊。相比線段樹來說,分塊演算法比較難實現,但是只要深入理解,就可以實現了,只不過需要一些資料結構的輔助。分塊實質來說就...