题意:由格子组成的一个房间,开始时每个格子都有1本书,然后来一Q个query,进行增、删、移动、查询矩形(x1, y1) - (x2, y2)内的书本数。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1892
——>>做的第一道二维树状数组题,写法基本和一维树状数组是一样的。
#include <cstdio>
#include <cstring>
#include <algorithm>using namespace std;const int maxn = 1000 + 10;
int C[maxn][maxn], a[maxn][maxn];int lowerbit(int x)
{return x&(-x);
}
int sum(int x, int y) //BIT求和
{int ret = 0;for(int i = x; i > 0; i -= lowerbit(i))for(int j = y; j > 0; j -= lowerbit(j))ret += C[i][j];return ret;
}
void add(int x, int y, int n) //BIT加法
{for(int i = x; i < maxn; i += lowerbit(i))for(int j = y; j < maxn; j += lowerbit(j))C[i][j] += n;
}
void del(int x, int y, int n) //BIT减法
{add(x, y, -n);
}
void mov(int x1, int y1, int x2, int y2, int n) //BIT移动
{add(x1, y1, -n);add(x2, y2, n);
}
int main()
{int T, Q, x1, y1, x2, y2, n1, cnt = 1;char c;scanf("%d", &T);while(T--){scanf("%d", &Q);printf("Case %d:\n", cnt++);for(int i = 1; i < maxn; i++)for(int j = 1; j < maxn; j++){a[i][j] = 1;C[i][j] = lowerbit(i)*lowerbit(j); //初始化C}while(Q--){scanf("\n%c", &c);switch(c){case 'A':{scanf("%d%d%d", &x1, &y1, &n1);x1++;y1++;add(x1, y1, n1);a[x1][y1] += n1;break;}case 'D':{scanf("%d%d%d", &x1, &y1, &n1);x1++;y1++;if(a[x1][y1] >= n1){del(x1, y1, n1);a[x1][y1] -= n1;}else{del(x1, y1, a[x1][y1]);a[x1][y1] = 0;}break;}case 'M':{scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &n1);x1++;y1++;x2++;y2++;if(a[x1][y1] >= n1){mov(x1, y1, x2, y2, n1);a[x1][y1] -= n1;a[x2][y2] += n1;}else{mov(x1, y1, x2, y2, a[x1][y1]);a[x2][y2] += a[x1][y1];a[x1][y1] = 0;}break;}case 'S':{scanf("%d%d%d%d", &x1, &y1, &x2, &y2);x1++;y1++;x2++;y2++;if(x1 > x2) swap(x1, x2);if(y1 > y2) swap(y1, y2);printf("%d\n", sum(x2, y2)-sum(x2, y1-1)-sum(x1-1, y2)+sum(x1-1, y1-1));break;}}}}return 0;
}
其中有个纠心的不明白,
对于add和sum
如果这样写:直接用参数x和y来做循环变量:
void add(int x, int y, int n) //BIT加法
{for(; x < maxn; x += lowerbit(x))for(; y < maxn; y += lowerbit(y))C[x][y] += n;
}
WA!WA!WA!……