POJ 2155 Matrix(二维树状数组)
2016-03-14 22:08
302 查看
http://poj.org/problem?id=2155
题意:操作C表示让左上角为(x1,y1)右下角为(x2,y2)的矩形内所有的01取反,一开始的时候全部为0。Q询问(x,y)内是0还是1。
这道题可以把01取反看成是操作C的累加,如果某个单元被操作了奇数次,那么相当于取反,否则就是没有动。这道题和一维情况中改变区间查询点的情况类似,只是将一维升级成二维。如果现在要改变左上角为(x1,y1)右下角为(x2,y2)的矩形,那么只要给一个二维数组中(x1,y1)(x2+1,y2+1)(x1,y2+1)(x1+1,y2)全部加上1,以(x1,y1)为例,在查询(x,y)的时候,通过累加,会把以(1,1)为左上角,(x,y)为右下角的矩形中所有的数加起来,那么如果(x1,y1)在这范围内,对(x,y)而言,就被操作了一次。综合起来,就是把以(x1,y1)为左上角,(n,n)为右下角的矩形内01取反。同理,其他也是一样的。最后相互抵消后,相当于是让左上角为(x1,y1)右下角为(x2,y2)的矩形内所有的01取反。
题意:操作C表示让左上角为(x1,y1)右下角为(x2,y2)的矩形内所有的01取反,一开始的时候全部为0。Q询问(x,y)内是0还是1。
这道题可以把01取反看成是操作C的累加,如果某个单元被操作了奇数次,那么相当于取反,否则就是没有动。这道题和一维情况中改变区间查询点的情况类似,只是将一维升级成二维。如果现在要改变左上角为(x1,y1)右下角为(x2,y2)的矩形,那么只要给一个二维数组中(x1,y1)(x2+1,y2+1)(x1,y2+1)(x1+1,y2)全部加上1,以(x1,y1)为例,在查询(x,y)的时候,通过累加,会把以(1,1)为左上角,(x,y)为右下角的矩形中所有的数加起来,那么如果(x1,y1)在这范围内,对(x,y)而言,就被操作了一次。综合起来,就是把以(x1,y1)为左上角,(n,n)为右下角的矩形内01取反。同理,其他也是一样的。最后相互抵消后,相当于是让左上角为(x1,y1)右下角为(x2,y2)的矩形内所有的01取反。
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define N 1005 using namespace std; int n; char s[3]; int c ; int lowbit(int x) { return x&(-x); } void change(int x, int y, int d) { int i = y; while(x <= n) { y = i; while(y <= n) { c[x][y] += d; c[x][y] %= 2; y += lowbit(y); } x += lowbit(x); } } int query(int x, int y) { int i = y, sum = 0; while(x > 0) { y = i; while(y > 0) { sum += c[x][y]; sum %= 2; y -= lowbit(y); } x -= lowbit(x); } return sum; } int main() { int T, m, ans, x, y, x2, y2, x1, y1; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); memset(c, 0, sizeof(c)); for (int i = 1; i <= m; i++) { scanf("%s", &s); if (s[0] == 'C') { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); change(x2+1, y2+1, 1); change(x1, y2+1, 1); change(x2+1, y1, 1); change(x1, y1, 1); } if (s[0] == 'Q') { scanf("%d%d", &x, &y); ans = query(x, y); printf("%d\n", ans); } } if (T) printf("\n"); } return 0; }
相关文章推荐
- 环信--即时通讯平台
- jQuery省市区三级联动插件
- ANDROID SHAPE画圆形背景_ANDROID实现角标布局
- 找工作感想
- 图片保存1
- 第56课:Spark SQL和DataFrame的本质
- 设计模式学习笔记——模板方法模式
- Problem E: 结构体---点坐标结构体
- 关于时间的思考
- 对接联调是一个情商活
- C++的异常安全性
- HDU3374
- RedHat升级Python2.6到Python3.4.3版本
- 十进制转二进制,八进制,十六进制(查表法)
- Android中的一些基础知识(三)
- Linux下Nginx+tomcat应用系统性能优化
- C++编译期多态与运行期多态
- iOS 面试题 (一)
- 矩阵分解——三角分解(Cholesky 分解)
- 编译错误的处理及译编过程及清理