【模板】分块
今天写分块的时候模板忘光了,故写以记之。
Code
Init
void init()
{
sz = sqrt(n), block = n / sz + (n % sz != 0);
for (int i = 1; i <= block; i ++)
st[i] = (i - 1) * sz + 1, ed[i] = i * sz;
ed[block] = n;
for (int i = 1; i <= block; i ++)
for (int j = st[i]; j <= ed[i]; j ++)
belong[j] = i;
}
其中块长视题目情况而改变,一般为 \(\sqrt n\)。
Modify / Query
void/int function(int x, int y)
{
int bx = belong[x], by = belong[y];
// pushdown(bx), pushdown(by); 根据题目情况而改变
if (by <= bx + 1) // 特判没有完整块的情况
{
for (int i = x; i <= y; i ++)
...;
return ...;
}
for (int i = x; i <= st[bx]; i ++) ...;
for (int i = st[by]; i <= y; i ++) ...;
for (int i = bx + 1; i <= by - 1; i ++) ...;
}
区间和
void modify(int x, int y, int k)
{
int bx = belong[x], by = belong[y];
if (by - bx <= 1)
{
for (int i = x; i <= y; i ++)
a[i] += k, sum[belong[i]] += k;
return;
}
for (int i = x; i <= ed[bx]; i ++) a[i] += k, sum[bx] += k;
for (int i = bx + 1; i <= by - 1; i ++) tag[i] += k;
for (int i = st[by]; i <= y; i ++) a[i] += k, sum[by] += k;
}
int query(int x, int y)
{
int bx = belong[x], by = belong[y];
if (by - bx <= 1)
{
int res = 0;
for (int i = x; i <= y; i ++) res += a[i] + tag[belong[i]];
return res;
}
int res = 0;
for (int i = x; i <= ed[bx]; i ++) res += a[i] + tag[bx];
for (int i = bx + 1; i <= by - 1; i ++)
res += sum[i] + tag[i] * (ed[i] - st[i] + 1);
for (int i = st[by]; i <= y; i ++) res += a[i] + tag[by];
return res;
}

浙公网安备 33010602011771号