分塊 定期重構

2022-01-17 07:49:29 字數 1324 閱讀 6124

講真的,定期重構這東西在網上部落格蠻少的

hzwer出了數列分塊入門1-9,其中數列分塊入門6就是定期重構

你需要支援的操作是:單點插入,單點查詢a[r]是多少,這道題目雖然資料隨機,但是想要拿全分那肯定還是得要寫個定期重構的。

大佬的說法:將每根號 n 個操作分為一組,每次每組結束後將當前所有組的修改放 到數列中去 ------曹hl

每次詢問考慮剩餘的修改操作對當前詢問的影響 ,分次進行數列重構

定期重構我認為就是在每單位個(根號n個)操作完成後對於分塊數列進行重組,以維持演算法的時間複雜度,保證結構穩定,(類似於「splay」)不會出現一種單塊超級長的情況,否則毒瘤資料會卡得你的分塊演算法超時。

你首先確定多少次操作後重構一次(大多數情況是根號n,但是具體情況要具體分析),然後每單位個修改操作之後就進行一次重構,維護數列的穩定(蠻容易的,看**,唯一複雜點就是資訊的複製)

#include using

namespace

std;

#define int long long

int a[200005], n, l[1005], r[1005], block, t = 0, q = 0

;int k[1000

];int c[1000][1005], cc[1000][1005

];int insert(int l, int

r);int ask(int

r);int

deb();

signed main()

//初始化分塊以及記錄每一塊裡面元素個數

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

for (int j = l[i]; j <= r[i]; j++) c[i][j - l[i] + 1] =a[j];

//初始化每個塊裡面的元素

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

ask(r);

}return0;

}int

deb() //

"三指標法"(滑稽)

if (kk[now2] == 0

) kk[now2] = num - block * (now2 - 1

); t =now2;

for (int i = 1; i <= t; i++) k[i] =kk[i];

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

return0;

}int ask(int

r) int insert(int l, int

r)

整除分塊(數論分塊)

乙個有 趣的問題 求 sum n lfloor frac ni rfloor n leq 10 顯然不能直接做廢話 經過一番冷靜推理暴力打表 我們發現以下性質 1.large lfloor frac ni rfloor 最多只有 2 sqrt 種取值 證明 對於 i le sqrt,只有 sqrt ...

牛客oj 小C的棋王之路 暴力分塊 塊重構

傳送門 那場wa了12發還是過不去.主要是區間賦值的操作想複雜了.分享一下遇到的問題.考慮題目給的幾個操作 1.區間加 區間乘 這兩個沒什麼難度,乘的時候把塊裡面加法標記也乘一下就好了.2 區間賦值 這個其實可以用上面兩個操作推導出來,不要多加乙個標記去記錄 速度會慢而且增大 難度 可以乘0再加x就...

分塊 分塊練習三題

分塊嘛 馮巨道德午餐講過的 唯一不同的是可能需要st n ed n 來記錄一下範圍 例教主的魔法 板 include using namespace std define in read int in const int n 1e6 5 int n,q,a n b n add n int siz,m...