分塊 學習筆記

2022-02-01 19:46:53 字數 1482 閱讀 4235

當我們對於乙個很大陣列 \((1e5)\) 進行區間修改和區間查詢時,我們會想到線段樹的 \(nlog_n\) 的優秀效率。

分塊——優雅的暴力!!!

我們將區間分成每個大小為 \(s\) 的小塊,這樣我們的複雜度就會從 \(n\) 降到 \(\frac n s\) 的效率。

我們先將陣列分成長度為 \(s\) 小塊,用原下標除以 \(s\) 向上取整,就是他分塊後的小塊標號。

void init() 

}

若我們要將 \(l\) 到 \(r\) 的區間內都加上權值 \(w\)。

若這個區間在乙個小塊裡面

直接 \(s\) 的效率乙個乙個修改即可。

若這個區間橫跨了多個小塊

如下圖

我們先用 \(s\) 效率將左右兩端無法組成乙個塊的單點都加上。

然後對於中間的塊,乙個乙個塊都打上標記,跟線段樹上的標記差不多,最後區間查詢時加上即可。

void modify(int l, int r, int w) 

}else

}}

跟區間修改的思想類似

若這個區間在乙個小塊裡面

將這個塊裡標記值加上,在加上單點的值即可。

若這個區間橫跨了多個小塊

將無法組成左右無法組成乙個小塊的部分用上面的思路加和。

剩下的一塊一塊直接加上 \(sum[i]\) 即可。

inline int query(int l, int r) 

}else

} return ans;

}

自我感覺比線段樹好寫,而且在某些題上會比線段樹跑得快。

例如這個板子題

打一波廣告

#include #include #include #include #include using namespace std;

const int maxn = 1e5 + 50, inf = 0x3f3f3f3f;

inline int read()

int n, m, s;

int a[maxn];

int bel[maxn], size[maxn], sum[maxn], l[maxn], r[maxn];

int tag[maxn];

void init()

}void modify(int l, int r, int w)

}else }}

inline int query(int l, int r)

}else

} return ans;

}int main()

init();

while (m --) else

} return 0;

}

分塊學習筆記

在我不知道分塊以前,我一直以為分塊是乙個非常牛逼的東西。在我多次學習並且處於懵逼狀態的時候,我一直以為這輩子我不會分塊了。直到一天我學會了他。ps 乙個小建議,學習新知識要在上午哦 下面我就把剛剛學會的分塊做了一下總結。主要思想 分塊是乙個很暴力的演算法,跟普通的列舉暴力差不了多少。對於乙個長度為n...

分塊 學習筆記

前言 內容參考自感謝。分塊,是一種優雅的暴力,它通過對數列分段,完成對數列一些區間操作和區間查詢的操作,是一種根號演算法。本文屬於分塊入門筆記,旨在零基礎的同學學會分塊。1 建塊 在建塊伊始,我們需要完成一下幾個任務 1.確定塊的大小 2.確定塊的數量 3.標記每個塊的左右邊界 4.標記每個元素所屬...

分塊學習筆記

題面傳送門 演算法簡介 分塊主要是乙個修改,維護區間的東西,它可以做到一邊修改一邊查詢,區間修改 o sqrt n 區間查詢 o sqrt n 單點修改 o 1 單點查詢 o 1 演算法實現 初始化 首先要把基本陣列 以下簡稱 a 陣列,長度為 n 分成 m 塊。一般是分成 sqrt n 塊,當然也...