http://poj.org/problem?id=1195
题意:(一大坨的题)给你4种操作,0代表输入矩阵的宽度建立矩阵,1代表对矩阵中第x行y列的数加上a,2代表对坐标点(l,b)~(r,t)矩阵内的所有点求和并输出,3代表退出。
思路:首先看教程,二维树状数组说白了就是横向为1,2,1,4,1,2,1,8这样的树状数组,纵向也为1,2,1,4,1,2,1,8这样的树状数组,那么对其的操作其实就是重复到二维上而已,要搞清楚矩阵的意义。注意输入是从0开始的,所有坐标都要加一。
#include
#include
#include
#include
using namespace std;
typedef long long ll;
const int N = 1025;
int tree[N][N], n;//从当前元素开始连续往左求lowbit(x)个数的和
int lowbit(int x)
{
return -x&x;
}
void update(int i, int j, int val)
{
while(i <= n)
{
int tmp = j;
while(tmp <= n)
{
tree[i][tmp]+=val;
tmp+=lowbit(tmp);
}
i+=lowbit(i);
}
}
int sum(int i, int j)
{
int num = 0;
while(i > 0)//说明还有组可加
{
int tmp = j;
while(tmp > 0)
{
num+=tree[i][tmp];
tmp-=lowbit(tmp);
}
i-=lowbit(i);
}
return num;
}
int main()
{
// freopen("in.txt", "r", stdin);
int op, x, y, a, l, b, r, t;
memset(tree, 0, sizeof(tree));
while(1)
{
scanf("%d", &op);
if(op == 0) scanf("%d", &n);
else if(op == 1)
{
scanf("%d%d%d", &x, &y, &a);
update(++x, ++y, a);
}
else if(op == 2)
{
scanf("%d%d%d%d", &l, &b, &r, &t);
l++;
b++;
r++;
t++;
printf("%d\n", sum(r, t)-sum(l-1, t)-sum(r, b-1)+sum(l-1, b-1));
}
else if(op == 3) break;
}
return 0;
}