poj 2115 Matrix

题意:

给出一个矩阵,有两种操作:

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 }

 

posted @ 2018-05-22 23:11  qrfkickit  阅读(108)  评论(0编辑  收藏  举报