LOJ6277. 数列分块入门 1 题解
涉及操作:
- 区间更新;
- 单点查询。
解题思路:
数列分块。
a[i]
表示:第i个数自己存储的值block
表示每个分块的最大尺寸belong[i]
表示:第i个数所属的分块tag[i]
表示:第i个分块的累加值
示例程序:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 50050;
/**
a[i] 表示:第i个数自己存储的值
block: 表示每个分块的最大尺寸
belong[i] 表示:第i个数所属的分块
tag[i] 表示:第i个分块的累加值
*/
int n, block, a[maxn], belong[maxn], tag[maxn];
void add(int l, int r, int val) { // 将 [l,r] 都加val
for (int i = l; i <= min(belong[l]*block, r); i ++)
a[i] += val;
if (belong[l] != belong[r])
for (int i = (belong[r]-1)*block+1; i <= r; i ++)
a[i] += val;
for (int i = belong[l]+1; i < belong[r]; i ++)
tag[i] += val;
}
int main() {
ios::sync_with_stdio(0);
cin >> n;
block = sqrt(n);
for (int i = 1; i <= n; i ++) {
cin >> a[i];
belong[i] = (i - 1) / block + 1;
}
for (int i = 0; i < n; i ++) {
int op, l, r, c;
cin >> op >> l >> r >> c;
if (op == 0) { // 将[l,r]都加c
add(l, r, c);
}
else { // 询问 a[r] 的值
cout << a[r] + tag[belong[r]] << endl;
}
}
return 0;
}