题意:
给出一个矩阵,有两种操作:
1.翻转给定的子矩阵;
2.查询a[i][j]的值。
思路:
树状数组是从小到大更新的。
这个题用二维树状数组可以解决,假设是一维树状数组,
0 0 0 0 0 0
我们把第三个到第四个翻转,变成
0 0 1 1 -1 0
sum[1] = 0,sum[2] = 0,sum[3] = 1,sum[4] = 1,sum[5] = 0,sum[6] = 0
所以类似一维的bit,但是要用到容斥原理,多减的要加回来。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 const int N = 1005; 6 int c[N][N]; 7 int n; 8 int lowbit(int x) 9 { 10 return x&(-x); 11 } 12 void add(int x,int y) 13 { 14 for (int i = x;i <= n;i += lowbit(i)) 15 { 16 for (int j = y;j <= n;j += lowbit(j)) 17 { 18 c[i][j] += 1; 19 } 20 } 21 } 22 int getsum(int x,int y) 23 { 24 int ans = 0; 25 for (int i = x;i > 0;i -= lowbit(i)) 26 { 27 for (int j = y;j > 0;j -= lowbit(j)) 28 { 29 ans += c[i][j]; 30 } 31 } 32 return ans; 33 } 34 int main() 35 { 36 int T; 37 scanf("%d",&T); 38 while (T--) 39 { 40 int op; 41 scanf("%d%d",&n,&op); 42 memset(c,0,sizeof(c)); 43 while (op--) 44 { 45 char s[5]; 46 scanf("%s",s); 47 if (s[0] == 'C') 48 { 49 int x1,y1,x2,y2; 50 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 51 add(x1,y1); 52 add(x2 + 1,y1); 53 add(x1,y2 + 1); 54 add(x2 + 1,y2 + 1); 55 } 56 if (s[0] == 'Q') 57 { 58 int x,y; 59 scanf("%d%d",&x,&y); 60 int ans = getsum(x,y); 61 if (ans % 2) puts("1"); 62 else puts("0"); 63 } 64 } 65 if (T) puts(""); 66 } 67 return 0; 68 }