分塊演算法實質上是一種是通過分成多塊後在每塊上打標記以實現快速區間修改,區間查詢的一種演算法。其均攤時間複雜度為o(n
)o(\sqrt n)
o(n)。
分塊演算法相較於各種高階資料結構,具有簡便易寫,方便除錯等多種優點。在同等資料規模下,如 1e5
1e51e
5 ,其時間效率並不會低太多,在很多時反而是一種更好的選擇。
為了使得其有著最穩定的時間複雜度,我們經常將乙個長度為n
nn的序列分為n
\sqrt n
n個大小為n
\sqrt n
n的塊,如果 n
nn 不是完全平方數,則序列最右端會多出乙個角塊。
比如給定序列:因為11 2 3 4 5 6 7 8 9 10
那麼分塊為:
0\sqrt 10
10的值向上取整為4
44,所以分為4
44塊,前3
33塊大小為3
33,最後乙個是角塊大小為111。
而我們要有乙個記錄值,記錄每乙個序號屬於哪一塊。
根據上圖,1,2
,31,2,3
1,2,
3屬於第一塊,4,5
,64,5,6
4,5,
6屬於第二塊,7,8
,97,8,9
7,8,
9屬於第三塊,10
1010
屬於第四塊。
獲取每乙個序號的所在塊:
int n;
//總個數
int block=
sqrt
(n);
//每一塊大小
for(
int i=
1; i<=n; i++
)
namo,如何用分塊來維護區間最值?比如這題:給定乙個長的為n數列,求出任意區間[l,r]的最大值(1≤
l,r≤
n)(l
≤r)(1 \leq l,r \leq n)(l \leq r)
(1≤l,r
≤n)(
l≤r)
學此之前,我想到的解法有:線段樹,樹狀陣列,滑動視窗。
但是現在可以拿分塊做!
拿上面這張圖,我們現在給每個點上加了乙個權值,每個塊維護一下塊內最大值,這樣當我們查詢任意乙個區間 max
([l,
r]max([l,r]
max([l
,r])時:
所以總時間複雜度是o(n
)o(\sqrt n)
o(n)。
接下來是區間修改:
所以總時間複雜度也是o(n
)o(\sqrt n)
o(n)。
當然分塊還可以解決很多區間問題,可以參考:oi-wiki
比如這題:給出乙個長為 n
nn的數列,以及n
nn個操作,操作涉及區間加法,詢問區間內小於某個值x
xx的前驅(比其小的最大元素)。
ac**:
**:分塊其實是一種思想,其本質是一種樹形結構,它是一種只有三層的樹,形態如下:
莫隊(待補…)
模板 資料結構 分塊
分塊這麼名字,聽起來十分的高大上 並沒有 但是實際 板子 理解起來不是很難.對於乙個需要維護某種區間上的資訊的序列,我們可以將其拆分為幾個子區間,也就是塊.這樣,對於每乙個塊,我們可以分別維護塊中的某乙個值,在查詢區間中的該值時,只需要將區間落到塊上,進行求解,就可以大大縮小複雜度.相較於線段樹 o...
資料結構之塊狀鍊錶
1 概述 在進行演算法設計時,我們常用的兩種線性資料結構是陣列和鍊錶。它們各有優缺點。陣列特點是元素在記憶體中緊挨著儲存,因而優點是定位快 o 1 缺點是插入刪除慢 o n 而鍊錶則不同,它通過指標將不同位置的元素鏈結起來,因而優缺點與陣列正好相反 定位慢 o n 插入刪除快 o 1 本文介紹一種新...
資料結構複習之分塊
分塊大暴力!分塊大暴力!分塊是乙個具有很強普適性的資料結構。可以適用於許多區間操作,只是效率略低了一點。分塊大體的套路如下 預處理出整塊的貢獻,暴力搞邊界兩個非完整塊的貢獻。分塊由鬼畜證明每個塊的大小為sqrt n 的話複雜度比較好。一下為分塊板子 解釋一下幾個陣列的意思 block是每個塊的大小,...