POJ 2155 Matrix (2维树状数组)

POJ-Matrix

题意:给你一个n*n矩阵的灯泡,灯泡的初始状态都为0,T次操作,分别是翻转操作:将x1,y1 --- x2, y2的灯泡状态反转 和 查询操作 找出x1, y1位置灯泡的状态。

题解:开一个2维树状数组进行更新操作。

假设我们现在需要翻转A区域内的灯泡, 我们就需要先将ABCD4个区域一起转换,然后再将CB,BD翻转,再将D翻转,这样结束之后就只有A的状态翻转了,所以我们需要先以(x1,y1)为起点更新ABCD区域,再以(x2+1,y1), (x1,y2+1)对BD, CD进行更新,最后以(x2+1,y2+1)进行更新。

 1 #include<iostream>
 2 #include<string>
 3 #include<cstring>
 4 using namespace std;
 5 const int N = 1000+5;
 6 int dp[N][N];
 7 int n, m;
 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         for(int j = y; j <= n; j += lowbit(j))
16             dp[i][j]++;
17 }
18 int Query(int x, int y)
19 {
20     int cnt = 0;
21     for(int i = x; i > 0; i -= lowbit(i))
22         for(int j = y; j > 0; j -= lowbit(j))
23            cnt += dp[i][j];
24     return cnt;
25 }
26 int main()
27 {
28     ios::sync_with_stdio(false);
29     cin.tie(0);
30     cout.tie(0);
31     int t;
32     cin >> t;
33     while(t--)
34     {
35         cin >> n >> m;
36         memset(dp, 0, sizeof(dp));
37         string str;
38         int x1, y1, x2, y2;
39         while(m--)
40         {
41             cin >> str >> x1 >> y1;
42             if(str[0] == 'C')
43             {
44                 cin >> x2 >> y2;
45                 Add(x2+1,y2+1);
46                 Add(x1,y1);
47                 Add(x1,y2+1);
48                 Add(x2+1,y1);
49             }
50             else
51             {
52                 if(Query(x1,y1)&1) cout << 1 << endl;
53                 else cout << 0 << endl;
54             }
55         }
56         cout << endl;
57     }
58     return 0;
59 }
原文地址:https://www.cnblogs.com/MingSD/p/8405578.html