1. 程式人生 > >POJ 2155 Matrix (2維樹狀數組)

POJ 2155 Matrix (2維樹狀數組)

lan href mat bit pan += ref esp ons

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 }

POJ 2155 Matrix (2維樹狀數組)