poj 2155 Matrix (二维树状数组)
题意:给你一个矩阵开始全是0,然后给你两种指令,第一种:C x1,y1,x2,y2 就是将左上角为x1,y1,右下角为x2,y2,的这个矩阵内的数字全部翻转,0变1,1变0 第二种:Q x1 y1,输出举证x1,y1,位置的数值
思路:该题的巧妙之处是反转的重叠抵消,记住要向上统计,向下修改;二维情况,最主要的是理解那个数组中的每个点保存的值的意义(一个矩形区域的总和);最后记住取余;
此题参考博客 http://blog.csdn.net/xymscau/article/details/6601298
树状数组参考博客 http://www.cnblogs.com/zhangshu/archive/2011/08/16/2141396.html
特别好的树状数组讲解 http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees#prob
代码:
#include <iostream> #include <cstdio> #include <cstring> #define maxn 1005 using namespace std; int tree[maxn*2][maxn*2]; int n; int lowbit(int x) { return x&(-x); } int getnum(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+=tree[i][j]; } return ans; } void updata(int x,int y,int val) { for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=n;j+=lowbit(j)) tree[i][j]+=val; } int main() { int t; scanf("%d",&t); while(t--) { int k; scanf("%d %d",&n,&k); getchar(); memset(tree,0,sizeof(tree)); while(k--) { char str; scanf("%c",&str); if(str=='Q') { int x,y; scanf("%d %d",&x,&y); getchar(); cout<<getnum(x,y)%2<<endl; } else { int x1,y1,x2,y2; scanf("%d %d %d %d",&x1,&y1,&x2,&y2); getchar(); updata(x1,y1,1); updata(x1,y2+1,1); updata(x2+1,y1,1); updata(x2+1,y2+1,1); } } cout<<endl; } return 0; }