http://acm.hdu.edu.cn/showproblem.php?pid=2642
题目大意:一个星空,二维的.上面有1000*1000的格点,每个格点上有星星在闪烁.一开始时星星全部暗淡着,有Q个操作:
B x y 点亮一盏星星
D x y 熄灭一盏星星
Q fx tx fy ty 查询这个矩形里面亮着的星星的个数.
题解:首先,注意输入的x,y可能是(0,0),这样一来,用树状数组就不好维护了,所以将之平移一个单位,每当读入一对坐标,要进行x++,y++..
其次,输入的查询,矩形的fx,tx大小未定,所以用:if(fx>tx)swap(fx,tx);进行判断一下
最后,星星点亮了可能还会再次点亮,所以需要加上一个状态数组进行判断.
#include<iostream> #include<math.h> #include<algorithm> #include<stdlib.h> #include<time.h> using namespace std; #define ll long long #define re(i,n) for(int i=0;i<n;i++) const int maxn = 1007; int a[maxn][maxn]; bool sta[maxn][maxn]; int lowbit(int x){ return x&-x; } void update(int x, int y, int d){ for (int i = x; i < maxn; i+=lowbit(i)){ for (int j = y; j < maxn; j+=lowbit(j)){ a[i][j] += d; } } } int query(int x, int y){ int ans = 0; for (int i = x; i>0; i -= lowbit(i)){ for (int j = y; j>0; j -= lowbit(j)){ ans += a[i][j]; } } return ans; } int main(){ freopen("in.txt", "r", stdin); int q; cin >> q; memset(a, 0, sizeof(a)), memset(sta, 0, sizeof(sta)); while (q--){ char op[2]; scanf("%s", op); if (op[0] == 'Q'){ int fx, fy, tx, ty; scanf("%d%d%d%d", &fx, &tx, &fy, &ty); fx++, fy++, tx++, ty++; if (fx>tx)swap(fx, tx); if (fy > ty)swap(fy, ty); fx--, fy--; int ans = query(tx, ty) + query(fx, fy) - query(tx, fy) - query(fx, ty); printf("%d ", ans); } else{ int x, y; scanf("%d%d", &x, &y); x++, y++; if (op[0] == 'B'){ if (sta[x][y])continue; update(x, y, 1), sta[x][y] = 1; } else{ if (sta[x][y] == false)continue; update(x, y, -1), sta[x][y] = 0; } } } return 0; }