[poj 1195] Mobile phones(二维树状数组)

来源:互联网 发布:淘宝评论期限 编辑:程序博客网 时间:2024/05/03 19:30

题意是给你一系列对矩阵的操作,然后询问矩阵的区间和。
有四种指令:
0 S,表示建立一个S*S大小的矩阵,初始全为零。
1 X Y A,表示把(x, y)坐标的数字加上A。
2 L B R T,表示求[L, T]到[R, B]范围矩阵的和。
3,表示此组数据结束。
只要从二维方向上分别进行树状数组的更新即可,只要会了一维的树状数组,那么二维的代码就非常好理解了。
注意到这道题是从[0, 0]开始的,所以输入的坐标值都要加上1。
#include<iostream>
#include<cstdio>
using namespace std;

#define maxn 1025

int num[maxn][maxn];
int n;

int lowbit(int x)
{
return x & (-x);
}

void update(int x, int y, int a)
{
for(int i = x; i <= n; i += lowbit(i))
{
for(int j = y; j <= n; j += lowbit(j))
{
num[i][j] += a;
}
}
}

int getsum(int x, int y)
{
int sum = 0;
for(int i = x; i > 0; i -= lowbit(i))
{
for(int j = y; j > 0; j -= lowbit(j))
{
sum += num[i][j];
}
}
return sum;
}

int main()
{
int op;
int x, y, a;
int l, b, r, t;
while(~scanf("%d", &op))
{
if(op == 0)
{
scanf("%d", &n);
memset(num, 0, sizeof(num));
}
else if(op == 1)
{
scanf("%d%d%d", &x, &y, &a);
update(x+1, y+1, a);
}
else if(op == 2)
{
scanf("%d%d%d%d", &l, &b, &r, &t);
l++, b++, r++, t++;
int re = getsum(l-1, b-1) - getsum(l-1, t) - getsum(r, b-1) + getsum(r, t);
printf("%d\n", re);
}
else if(op == 3)
{
break;
}
}
return 0;
}
0 0