今天写分块的时候模板忘光了,故写以记之。

Code

Init

1
2
3
4
5
6
7
8
9
10
11
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;
}

其中块长视题目情况而改变,一般为 n\sqrt n

Modify / Query

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 ++) ...;
}

区间和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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;
}