voidInit() { 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。
Modify / Query
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
void/intFunction(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 ++) ...; }
voidmodify(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; }
intquery(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; }