标签:
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2642
题目大意:
现在假设天空是一个二维平面(1000*1000)。坐标从(0,0)点开始。现在给出N条信息。
"B X Y",B为字符,x、y是整数,表示将坐标(x,y)的星星变亮。
"D XY",D为字符,x、y是整数,表示将坐标(x,y)的星星变暗。
"Q X1 X2 Y1 Y2",Q是字符,X1、X2、Y1、Y2是整数,表示问有多少颗星星在X1、X2、
Y1、Y2确定的矩形中。
思路:
建立一个二维的树状数组,单点更新,区间求值。其实和一维的差不多。只不过第i个元素变
为了第x行第y列的元素。更新和求值都是二维维护数组数组。再用一个二维数组Mark[][]表
示(x、y)处的星星的明暗情况。因为坐标是从(0,0)点开始的,而Lowbit(0) = 0,所以,另
所有的横纵坐标都加1,使坐标从(1,1)点开始。
AC代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 1010; int Tree[MAXN][MAXN],N; bool Mark[MAXN][MAXN]; int Lowbit(int i) { return i & (-i); } void Update(int x,int y,int num) { for(int i = x; i <= MAXN; i += Lowbit(i)) for(int j = y; j <= MAXN; j += Lowbit(j)) Tree[i][j] += num; } int Query(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 += Tree[i][j]; return sum; } int main() { char str[3]; int x,y; while(cin >> N) { memset(Tree,0,sizeof(Tree)); memset(Mark,0,sizeof(Mark)); while(N--) { cin >> str; if(str[0] == 'B') { cin >> x >> y; x++,y++; if(!Mark[x][y]) { Mark[x][y] = 1; Update(x,y,1); } } else if(str[0] == 'D') { cin >> x >> y; x++,y++; if(Mark[x][y]) { Mark[x][y] = 0; Update(x,y,-1); } } else if(str[0] == 'Q') { int x1,x2,y1,y2; cin >> x1 >> x2 >> y1 >> y2; x1++,x2++,y1++,y2++; if(x1 < x2) swap(x1,x2); if(y1 < y2) swap(y1,y2); int res = Query(x1,y1) - Query(x1,y2-1) - Query(x2-1,y1) + Query(x2-1,y2-1); cout << res << endl; } } } return 0; }
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/45339199