题意:给你一个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 }