講真的,定期重構這東西在網上部落格蠻少的
hzwer出了數列分塊入門1-9,其中數列分塊入門6就是定期重構
你需要支援的操作是:單點插入,單點查詢a[r]是多少,這道題目雖然資料隨機,但是想要拿全分那肯定還是得要寫個定期重構的。
大佬的說法:將每根號 n 個操作分為一組,每次每組結束後將當前所有組的修改放 到數列中去 ------曹hl
每次詢問考慮剩餘的修改操作對當前詢問的影響 ,分次進行數列重構
定期重構我認為就是在每單位個(根號n個)操作完成後對於分塊數列進行重組,以維持演算法的時間複雜度,保證結構穩定,(類似於「splay」)不會出現一種單塊超級長的情況,否則毒瘤資料會卡得你的分塊演算法超時。
你首先確定多少次操作後重構一次(大多數情況是根號n,但是具體情況要具體分析),然後每單位個修改操作之後就進行一次重構,維護數列的穩定(蠻容易的,看**,唯一複雜點就是資訊的複製)
#include usingnamespace
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...