Submission #1245303

#TimeUsernameProblemLanguageResultExecution timeMemory
1245303ducdevPaint (COI20_paint)C++20
17 / 100
3094 ms64696 KiB
// Author: 4uckd3v - Nguyen Cao Duc #include <bits/stdc++.h> using namespace std; #define cell(x, y) (((x) - 1) * n + (y)) typedef long long ll; typedef pair<int, int> ii; const int MAX_N = 2e5; const int MAX_Q = 1e5; const int MOD = 1e9 + 7; const int dx[] = {1, 0, -1, 0}; const int dy[] = {0, 1, 0, -1}; struct Query { int x, y, color; Query() {}; Query(int x, int y, int color) : x(x), y(y), color(color) {}; }; struct DSU { vector<int> par, sz, lef, rig, color; vector<set<int>> border; int n; int findSet(int u) { return u == par[u] ? u : par[u] = findSet(par[u]); }; int getColor(int u) { return color[findSet(u)]; }; void setColor(int u, int c) { color[findSet(u)] = c; }; bool unionSet(int u, int v, int c) { u = findSet(u), v = findSet(v); if (u == v) return false; if (sz[u] < sz[v]) swap(u, v); if (border[u].size() < border[v].size()) border[u].swap(border[v]); for (int node : border[v]) if (findSet(node) != u) border[u].insert(node); setColor(u, c); sz[u] += sz[v]; par[v] = u; lef[u] = min(lef[u], lef[v]); rig[u] = max(rig[u], rig[v]); return true; }; DSU() {}; DSU(int n) : n(n) { par.resize(n + 1), color.resize(n + 1); lef.resize(n + 1), rig.resize(n + 1); border.resize(n + 1), sz.resize(n + 1); for (int u = 1; u <= n; u++) { par[u] = u; lef[u] = u, rig[u] = u; sz[u] = 1; }; }; }; int m, n, q; vector<Query> queries; vector<vector<int>> a; bool valid(int x, int y) { return (x >= 1 && x <= m && y >= 1 && y <= n); }; namespace SUBTASK_1 { const int MN = 1e4; bool vis[MN + 5]; vector<vector<int>> b; bool checkSubtask() { return m * n <= 1e4 && q <= 1e4; }; void dfs(int x, int y, int color) { vis[cell(x, y)] = true; for (int i = 0; i < 4; i++) { int u = x + dx[i]; int v = y + dy[i]; if (valid(u, v) && !vis[cell(u, v)] && b[u][v] == b[x][y]) dfs(u, v, color); }; b[x][y] = color; }; void Solve() { b = a; for (const Query &q : queries) { int x = q.x, y = q.y, color = q.color; for (int i = 1; i <= m * n; i++) vis[i] = false; dfs(x, y, color); }; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { cout << b[i][j] << " "; }; cout << '\n'; }; }; }; // namespace SUBTASK_1 namespace SUBTASK_2 { const int M = 1; const int N = MAX_N; const int Q = MAX_Q; bool checkSubtask() { return m <= M && n <= N && q <= Q; }; void Solve() { DSU DSU(n); for (int i = 1; i <= n; i++) { DSU.setColor(i, a[1][i]); }; for (int i = 1; i < n; i++) { if (a[1][i] == a[1][i + 1]) { DSU.unionSet(i, i + 1, a[1][i]); }; }; for (const Query &q : queries) { int idx = q.y, color = q.color; if (color == DSU.getColor(idx)) continue; DSU.setColor(idx, color); int root = DSU.findSet(idx); int l = DSU.lef[root], r = DSU.rig[root]; int newL = (l - 1 == 0 ? idx : DSU.findSet(l - 1)); int newR = (r + 1 > n ? idx : DSU.findSet(r + 1)); if (DSU.color[newL] == color) { DSU.unionSet(newL, idx, color); }; if (DSU.color[newR] == color) { DSU.unionSet(newR, idx, color); }; }; for (int i = 1; i <= n; i++) cout << DSU.getColor(i) << ' '; cout << '\n'; }; }; // namespace SUBTASK_2 void printMatrix(int m, int n, const vector<vector<int>> &a) { for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { cout << a[i][j] << ' '; }; cout << '\n'; }; }; namespace SUBTASK_3 { const int SIZE = 2e5; bool checkSubtask() { for (Query &q : queries) if (q.color > 1) return false; return true; }; vector<vector<int>> rotate(int m, int n, const vector<vector<int>> &a) { vector<vector<int>> b(n + 2, vector<int>(m + 2, 0)); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { b[i][j] = a[j][i]; }; }; return b; }; void Solve() { DSU DSU(m * n); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { int u = cell(i, j); DSU.setColor(u, a[i][j]); for (int k = 0; k < 4; k++) { int x = i + dx[k]; int y = j + dy[k]; if (valid(x, y)) { int v = cell(x, y); if (a[x][y] != a[i][j]) DSU.border[u].insert(v); else DSU.unionSet(u, v, a[x][y]); }; }; }; }; for (const Query &q : queries) { int x = q.x, y = q.y, color = q.color; int u = cell(x, y); if (color == DSU.getColor(u)) continue; int root = DSU.findSet(u); DSU.setColor(root, color); bool merged_in_pass = true; while (merged_in_pass) { merged_in_pass = false; set<int> current_border = DSU.border[root]; set<int> visited_neighbor_roots; for (int v_cell : current_border) { int v_root = DSU.findSet(v_cell); if (v_root == root || visited_neighbor_roots.count(v_root)) { continue; }; visited_neighbor_roots.insert(v_root); if (DSU.getColor(v_root) == color) { DSU.unionSet(root, v_root, color); root = DSU.findSet(root); merged_in_pass = true; }; }; }; }; for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { a[i][j] = DSU.getColor(cell(i, j)); }; }; printMatrix(m, n, a); }; }; // namespace SUBTASK_3 int main() { ios_base::sync_with_stdio(0); cin.tie(0); if (fopen("PAINT.INP", "r")) { freopen("PAINT.INP", "r", stdin); freopen("PAINT.OUT", "w", stdout); }; cin >> m >> n; a.resize(m + 2, vector<int>(n + 2, 0)); for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { cin >> a[i][j]; }; }; cin >> q; queries.resize(q); for (Query &q : queries) cin >> q.x >> q.y >> q.color; if (SUBTASK_1::checkSubtask()) return SUBTASK_1::Solve(), 0; if (SUBTASK_2::checkSubtask()) return SUBTASK_2::Solve(), 0; SUBTASK_3::Solve(); };

Compilation message (stderr)

paint.cpp: In function 'int main()':
paint.cpp:257:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  257 |         freopen("PAINT.INP", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
paint.cpp:258:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  258 |         freopen("PAINT.OUT", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...