分塊演算法總結

2021-08-27 16:12:25 字數 1560 閱讀 5744

分塊演算法顧名思義,就是將乙個序列分成若干個部分(塊)來解決

線段樹也可以解決分塊的問題,但這裡只介紹分塊演算法

說是分塊,那麼一共要分幾塊呢?

據機房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.思想 如果我們需要對乙個特定的序列進行操作,那麼非常直觀 簡單的方法就是純暴力 不,那叫模擬 不過如果暴力能過的話,那就呵呵了。所以我們要想一些比較高能的資料結構 分塊。相比線段樹來說,分塊演算法比較難實現,但是只要深入理解,就可以實現了,只不過需要一些資料結構的輔助。分塊實質來說就...