模板 資料結構 分塊

2022-05-24 14:09:14 字數 2435 閱讀 4050

分塊這麼名字, 聽起來十分的高大上 並沒有 , 但是實際 板子 理解起來不是很難.

對於乙個需要維護某種區間上的資訊的序列, 我們可以將其拆分為幾個子區間, 也就是. 這樣, 對於每乙個塊, 我們可以分別維護塊中的某乙個值, 在查詢區間中的該值時, 只需要將區間落到塊上, 進行求解, 就可以大大縮小複雜度.

相較於線段樹( \(o(\log_2n)\) ), 分塊本身的複雜度是比較高(\(o(\sqrt n)\))的.

但是, 分塊( 相對線段樹 )有如下優點:

在考試時, 分塊也不失為一種得 騙 分的好辦法.

p3372 線段樹1為例.

首先, 我們將整個範圍分成若干一定大小的塊.

然後我們對於每個塊像線段樹的區間一樣進行預處理, 處理出每個塊的總和.

接下來進行操作, 對於每次操作( 無論是修改還是查詢 )的區間 \(\left[l,r\right]\) , 都有如下的幾種情況:

\(l\), \(r\) 在同乙個塊中:

此時我們無法利用分塊的性質, 但因為範圍不大( 最大\(\sqrt n\) ), 所以我們可以放心的直接操作.

\(l\), \(r\) 在相鄰的兩個塊中:

法同1.

\(l\), \(r\) 在不相鄰的塊中:

這時, 對於兩邊的塊( \(l\), \(r\) 兩端點所在的塊 ), 我們仍然直接處理, 但是中間的完整的塊, 我們就可以直接利用之前維護的值來更新了.

總複雜度:\(o(\sqrt n)\).

附:實際上, 分塊是乙個"原序列 -- 塊 -- 值"三層的樹形結構.

hzwer神仙的分塊九練為例.

所有 \(9\) 道題的傳送門均為libreoj

乙個基本的板子, 沒有什麼特別的地方.

# include # include # include # define maxn 50005

using namespace std;

int a[maxn];

int blk[maxn], sizb, taga[250]; // 每個點所屬的塊, 塊的大小, 每個塊的加標記

void add(int l, int r, int val) // 兩點在一塊或相鄰塊

for(int i = l; i <= blk[l]*sizb; i++)

a[i] += val;

for(int i = (blk[r]-1)*sizb+1; i <= r; i++)

a[i] += val; // 處理角塊

for(int i = blk[l]+1; i <= blk[r]-1; i++)

taga[i] += val;

}int main()

for(int i = 1; i <= n; i++)

else

}

return 0;

}

考慮到需要查詢某區間內小於 \(c^2\) 的個數, 我們需要對塊進行排序, 這樣可以通過二分查詢快速解決問題.

# include # include # include # include # include # define maxn 50005

using namespace std;

int a[maxn], blk[maxn], taga[250], sizb, n;

vectorv[250]; // v 用於維護每個塊中的順序

int query(int l, int r, int val)

return ans;

}void reset(int x) // 清空塊重新排序

void add(int l, int r, int val)

for(int i = l; i <= blk[l]*sizb; i++)

a[i] += val;

for(int i = (blk[r]-1)*sizb+1; i <= r; i++)

a[i] += val;

for(int i = blk[l]+1; i <= blk[r]-1; i++)

taga[i] += val;

reset(blk[l]); reset(blk[r]);

// 完整的塊每個數都被加上了乙個定值, 單調性不改變

}signed main()

for(int i = 1; i <= blk[n]; i++)

sort(v[i].begin(), v[i].end());

for(int i = 1; i <= n; i++)

else

}return 0;

}

塊狀資料結構 分塊

分塊演算法實質上是一種是通過分成多塊後在每塊上打標記以實現快速區間修改,區間查詢的一種演算法。其均攤時間複雜度為o n o sqrt n o n 分塊演算法相較於各種高階資料結構,具有簡便易寫,方便除錯等多種優點。在同等資料規模下,如 1e5 1e51e 5 其時間效率並不會低太多,在很多時反而是一...

資料結構複習之分塊

分塊大暴力!分塊大暴力!分塊是乙個具有很強普適性的資料結構。可以適用於許多區間操作,只是效率略低了一點。分塊大體的套路如下 預處理出整塊的貢獻,暴力搞邊界兩個非完整塊的貢獻。分塊由鬼畜證明每個塊的大小為sqrt n 的話複雜度比較好。一下為分塊板子 解釋一下幾個陣列的意思 block是每個塊的大小,...

大話資料結構之 分塊索引

稠密索引因為索引項和資料集的記錄個數相同,所以控制項代價很大。為了減少索引項的個數,我們可以對資料集進行分塊,使其分塊有序,然後再對每一塊建立乙個索引項,從而減少索引項的個數。分塊有序,是把資料集的個數分成了若干塊,並且這些塊需要滿足兩個條件 對於分塊有序的資料集,將每塊對應乙個索引項,這種索引方法...