貌似是第一道传说中的二维的题目。
二维就是把单行数组变成了矩形数组
引用一下别人的图片:下面这个图片是更新(1,1)这个点所引发的树状数组的变化
由此我们不难看出,二维只是在一维的基础上向上拓展了一维。
更新和求开头到某一坐标的矩阵和和一维的操作差不多,只是多了一重循环
在求子矩阵和的时候则不能简单的右上矩阵和减左下矩阵和。
具体求子矩阵和的思路可以自己想想,不懂看下面输出函数的代码。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL long long
using namespace std;
const int mx = 2000;
LL val[mx][mx];
int s;
inline int lowbit(int x)
{
return x & (-x);
}
void update(int x, int y, int a)
{
for(int i=x; i<=s; i+=lowbit(i))
for(int j=y; j<=s; j+=lowbit(j))
val[i][j] += a;
}
LL Getsum(int l,int r)
{
LL ans = 0;
for(int i=l; i>0; i-=lowbit(i))
for(int j=r; j>0; j-=lowbit(j))
ans += val[i][j];
return ans;
}
int main()
{
// freopen("1195.txt","r",stdin);
int q;
while(~scanf("%d%d",&q,&s))
{
memset(val, 0, sizeof(val));
while(scanf("%d",&q),q!=3)
{
if(q==1)
{
int x,y,a;
scanf("%d %d %d",&x,&y,&a);
x++;y++;
update(x,y,a);
}
else if(q==2)
{
int l,b,r,t;
scanf("%d %d %d %d",&l,&b,&r,&t);
l++;b++;r++;t++;
printf("%I64d\n",Getsum(r,t) + Getsum(l-1,b-1) - Getsum(l-1,t) - Getsum(r,b-1));
}
}
}
return 0;
}