來自 hzwer 的九道非常經典的分塊題。
目前可以在 loj 上提交:here
1.給出乙個長度為 \(n\) 的數列,支援區間加,單點查值。
將序列分成長度為 \(s\) 的 \(\lceil\frac\rceil\) 塊。
設我們的操作區間為 \([l,r]\),稱被其完全包含的塊為整塊,否則為散塊。
可以發現整塊的數量不超過 \(\lceil\frac\rceil\),散塊的數量不超過 \(2\),於是散塊中元素的個數不超過 \(2s\)。
加法操作就可以在這 \(\lceil\frac\rceil\) 個整塊上打標記,散塊中的元素暴力加。
一次操作的時間複雜度為 \(o(\lceil\frac\rceil+s)\)。
單點查詢就直接輸出該位置的值加上所在塊的標記,複雜度是 \(o(1)\) 的。
注意到我們需要平衡修改操作的複雜度,即讓 \(\lceil\frac\rceil\) 和 \(s\) 盡量差的小。
於是取 \(s=\sqrt n\) 就可以做到 \(o(\sqrt n)\)。
總時間複雜度 \(o(n\sqrt n)\)。
2.給出乙個長度為 \(n\) 的數列,支援區間加,求乙個區間中小於乙個數 \(x\) 的元素數量。
可以考慮在每個塊內維護原序列排序後的序列。也就是每個塊維護乙個原塊,和乙個排序後的塊。
那麼對於乙個塊的詢問就可以 \(o(\log s)\) 二分一下完成。
散塊暴力統計,時間複雜度 \(o(s)\)。
那麼一次詢問的複雜度為 \(o(\lceil\frac\rceil\log s+s)\)。
對於修改操作,可以發現對於乙個整塊進行整體加法並不會改變其有序性。所以可以直接在 \(\lceil\frac\rceil\) 個整塊上打加法標記,複雜度 \(o(\lceil\frac\rceil)\)。
散塊暴力做加法,同時重新排序,時間複雜度 \(o(s+s\log s)\)。
於是一次修改的複雜度為 \(o(\lceil\frac\rceil+s\log s)\)。
取 \(s=\sqrt n\) 可以做到 \(o(\sqrt n\log n)\)。
數列分塊 1 9
如果還不了解什麼是分塊,清先閱讀分塊link這一篇文章 描述 給出乙個長為 n 的數列,以及 n 個操作,操作涉及區間加法,單點查值 題目 link qwq 首先看到這個題,是可以有很多思路的,這道題幾乎涉及很多的資料結構問題模板,但是主要這裡主要講解為數列分塊 其實早就予以給出了什麼是分塊,我們也...
數列分塊入門1 9 loj6277 6285
hzwer的講解 給出乙個長為 n 的數列,以及 n 個操作,操作涉及區間加法,單點查值。include include include using namespace std int n,a 50005 opt,uu,vv,ww,tag 305 blc,bel 50005 void add int...
分塊3 6279 數列分塊入門 3
題目描述 給出乙個長為 nn 的數列,以及 nn 個操作,操作涉及區間加法,詢問區間內小於某個值 xx 的前驅 比其小的最大元素 輸入格式 第一行輸入乙個數字 nn。第二行輸入 nn 個數字,第 ii 個數字為 a iai 以空格隔開。接下來輸入 nn 行詢問,每行輸入四個數字 mathrmopt ...