题目:题目链接
思路:每个空白区域当作一个并查集,因为正着使用并查集分割的话dfs会爆栈,判断过于复杂也会导致超时,我们采用离线反向操作,先全部涂好,然后把黑格子逐步涂白,我们把每个空白区域当作一个并查集,然后采用合并并查集的方法来做,好困啊,明天还有课,具体思路有空再写吧,先睡觉了。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 7 using namespace std; 8 9 #define y1 yy1 10 #define y2 _y2 11 12 const int maxn = 1000 + 5; 13 const int maxq = 10000 + 5; 14 15 int grid[maxn][maxn], x1[maxq], y1[maxq], x2[maxq], y2[maxq], num[maxn * maxn], n, m, q, sum, ans[maxq]; 16 17 int cx[] = { -1, 0, 1, 0 }; 18 int cy[] = { 0, -1, 0, 1 }; 19 20 void init(); 21 int cal(int, int); 22 bool judge(int, int); 23 void unite(int, int); 24 int _find(int); 25 void solve(); 26 27 int main() 28 { 29 ios::sync_with_stdio(0); 30 cin.tie(0); 31 32 cin >> n >> m >> q; 33 34 for (int i = 1; i <= q; ++i) { 35 cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; 36 if (x1[i] == x2[i]) 37 for (int j = y1[i]; j <= y2[i]; ++j) 38 ++grid[x1[i]][j]; 39 else 40 for (int j = x1[i]; j <= x2[i]; ++j) 41 ++grid[j][y1[i]]; 42 } 43 44 init(); 45 46 solve(); 47 48 for (int i = 1; i <= q; ++i) 49 cout << ans[i] << endl; 50 51 return 0; 52 } 53 54 void init() { 55 for (int i = 0; i <= n * m; ++i) 56 num[i] = i; 57 58 sum = n * m; 59 60 for (int i = 1; i <= n; ++i) { 61 for (int j = 1; j <= m; ++j) { 62 if (!grid[i][j]) { 63 for (int k = 0; k < 4; ++k) { 64 if (judge(i + cx[k], j + cy[k]) && !grid[i + cx[k]][j + cy[k]]) { 65 unite(cal(i, j), cal(i + cx[k], j + cy[k])); 66 } 67 } 68 } 69 else 70 --sum; 71 } 72 } 73 } 74 75 int cal(int x, int y) { 76 return (x - 1) * m + y; 77 } 78 79 bool judge(int x, int y) { 80 return x > 0 && x <= n && y > 0 && y <= m; 81 } 82 83 void unite(int x, int y) { 84 int a = _find(x), b = _find(y); 85 if (a == b) 86 return; 87 88 --sum; 89 num[a] = b; 90 } 91 92 int _find(int x) { 93 return x == num[x] ? x : num[x] = _find(num[x]); 94 } 95 96 void solve() { 97 for (int i = q; i > 0; --i) { 98 ans[i] = sum; 99 if (x1[i] == x2[i]) { 100 for (int j = y1[i]; j <= y2[i]; ++j) { 101 --grid[x1[i]][j]; 102 if (!grid[x1[i]][j]) { 103 ++sum; 104 for (int k = 0; k < 4; ++k) { 105 if (judge(x1[i] + cx[k], j + cy[k]) && !grid[x1[i] + cx[k]][j + cy[k]]) 106 unite(cal(x1[i], j), cal(x1[i] + cx[k], j + cy[k])); 107 } 108 } 109 } 110 } 111 else { 112 for (int j = x1[i]; j <= x2[i]; ++j) { 113 --grid[j][y1[i]]; 114 if (!grid[j][y1[i]]) { 115 ++sum; 116 for (int k = 0; k < 4; ++k) 117 if (judge(j + cx[k], y1[i] + cy[k]) && !grid[j + cx[k]][y1[i] + cy[k]]) 118 unite(cal(j, y1[i]), cal(j + cx[k], y1[i] + cy[k])); 119 } 120 } 121 } 122 } 123 }