题目大意:给你一个N*N的矩阵,初始化为0
三种操作
1 x y c:将(x,y)的值加c
2 x1 y1 x2 y2:询问区间(x1,y1)到(x2,y2)的和
3: 结束操作
解题思路:用二维树状数组可做
也可以一维的,分段维护
二维树状数组
#include <cstdio>
#include <cstring>
const int N = 1030;
int bit[N][N];
int n;
inline int lowbit(int x) {
return x & (-x);
}
void Modify(int x, int y, int c) {
while (y < N) {
bit[x][y] += c;
y += lowbit(y);
}
}
int Query(int x, int y) {
int ans = 0;
while (y) {
ans += bit[x][y];
y -= lowbit(y);
}
return ans;
}
void solve() {
memset(bit, 0, sizeof(bit));
int op;
int x1, y1, x2, y2, c;
while (scanf("%d", &op) && op != 3) {
if (op == 1) {
scanf("%d%d%d", &x1, &y1, &c);
x1++; y1++;
int tmp = Query(x1, y1) - Query(x1, y1 - 1);
if (tmp + c < 0) c = -tmp;
Modify(x1, y1, c);
}
else if (op == 2) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1++; x2++; y1++; y2++;
long long ans = 0;
for (int i = x1; i <= x2; i++)
ans += Query(i, y2) - Query(i, y1 - 1);
printf("%lld\n", ans);
}
}
}
int main() {
int t;
while (scanf("%d%d", &t, &n) != EOF) solve();
return 0;
}
一维的,分段维护
#include <cstdio>
#include <cstring>
const int N = 1030;
int bit[N][N];
int n;
inline int lowbit(int x) {
return x & (-x);
}
void Modify(int x, int y, int c) {
while (y < N) {
bit[x][y] += c;
y += lowbit(y);
}
}
int Query(int x, int y) {
int ans = 0;
while (y) {
ans += bit[x][y];
y -= lowbit(y);
}
return ans;
}
void solve() {
memset(bit, 0, sizeof(bit));
int op;
int x1, y1, x2, y2, c;
while (scanf("%d", &op) && op != 3) {
if (op == 1) {
scanf("%d%d%d", &x1, &y1, &c);
x1++; y1++;
int tmp = Query(x1, y1) - Query(x1, y1 - 1);
if (tmp + c < 0) c = -tmp;
Modify(x1, y1, c);
}
else if (op == 2) {
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1++; x2++; y1++; y2++;
long long ans = 0;
for (int i = x1; i <= x2; i++)
ans += Query(i, y2) - Query(i, y1 - 1);
printf("%lld\n", ans);
}
}
}
int main() {
int t;
while (scanf("%d%d", &t, &n) != EOF) solve();
return 0;
}