题目链接: 戳我
题目大意:
给你一个二维数组 a[][] , 有以下几种操作,0 S 就是把数组初始化为0
1 X Y A 就是让 a[X][y] = A;
2 L B R T 就是求矩阵a[L][B] 和 a[R][T] 所围矩形内的和
3 退出
简单的二维树状数组, 不懂得看这篇博客,挺好的, 尤其是还解释了树状数组lowbit 戳我
代码C++比G++快了一倍:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> using namespace std; #define clc(a, b) memset(a, b, sizeof(a)) const int inf = 0x3f; const int INF = 0x3f3f3f3f; const int maxn = 1050; int a[maxn][maxn], n; void Init() { clc(a, 0); } int lowbit(int x) { return x & -x; } void Add(int x, int yy, int val) { while(x <= n) { int y = yy; while(y <= n) { a[x][y] += val; y += lowbit(y); } x += lowbit(x); } } int Sum(int x, int y) { int sum = 0, yy; while(x) { yy = y; while(yy) { sum += a[x][yy]; yy -= lowbit(yy); } x -= lowbit(x); } return sum; } int main() { int op, x, y, l, x1, y1, x2, y2, sum; while(~scanf("%d", &op)) { scanf("%d", &n); if(op == 0) Init(); while(true) { scanf("%d", &op); if(op == 1) { scanf("%d %d %d", &x, &y, &l); Add(x+1, y+1, l); } else if(op == 2) { scanf("%d %d %d %d", &x1, &y1, &x2, &y2); x1++; y1++; x2++; y2++; sum = Sum(x2, y2) - Sum(x1-1, y2) - Sum(x2, y1-1) + Sum(x1-1, y1-1); printf("%d ", sum); } else break; } } }