Submission #467290

#TimeUsernameProblemLanguageResultExecution timeMemory
467290phathnvPaint (COI20_paint)C++17
31 / 100
3081 ms524292 KiB
#include <bits/stdc++.h> using namespace std; const int N = 200000; const int BLOCKSIZE = 444; int m, n, q, curInd; vector<vector<int>> ind; vector<int> adj[N]; map<int, vector<int>> s[N]; int root[N], sz[N], col[N]; void MergeMap(int u, int v) { for (auto &p : s[u]) { if (s[v].find(p.first) != s[v].end()) { auto &q = s[v][p.first]; if (p.second.size() < q.size()) swap(p.second, q); for (int x : q) p.second.push_back(x); s[v].erase(p.first); } } for (auto &p : s[v]) { assert(s[u].find(p.first) == s[u].end()); s[u][p.first] = p.second; } s[v].clear(); } int FindRoot(int u) { if (u == root[u]) return u; return root[u] = FindRoot(root[u]); } void Merge(int u, int v) { u = FindRoot(u); v = FindRoot(v); if (u == v) return; assert(col[u] == col[v]); if (sz[u] < sz[v]) swap(u, v); for (int x : adj[v]) adj[u].push_back(FindRoot(x)); adj[v].clear(); MergeMap(u, v); root[v] = u; sz[u] += sz[v]; if (sz[u] >= BLOCKSIZE) { vector<int> newAdj; for (int v : adj[u]) { v = FindRoot(v); if (v == u) continue; if (sz[v] >= BLOCKSIZE) { newAdj.push_back(v); adj[v].push_back(u); } else { s[u][col[v]].push_back(v); } } //cerr << adj[u].size() << ' ' << newAdj.size() << endl; adj[u] = newAdj; } } void Color(int u, int c) { u = FindRoot(u); col[u] = c; vector<pair<int, int>> shouldMerge, shouldDel; for (int v : adj[u]) { v = FindRoot(v); if (col[v] == c) shouldMerge.push_back({u, v}); } if (s[u].find(c) != s[u].end()) { vector<int> &a = s[u][c]; for (int v : a) { v = FindRoot(v); if (col[u] == col[v]) shouldMerge.push_back({u, v}); } a.clear(); } for (auto p : shouldMerge) Merge(p.first, p.second); u = FindRoot(u); if (sz[u] < BLOCKSIZE) { for (int v : adj[u]) { v = FindRoot(v); if (v != u && sz[v] >= BLOCKSIZE) s[v][c].push_back(u); } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> m >> n; ind.assign(m, vector<int>(n, 0)); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) ind[i][j] = curInd++; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { if (i + 1 < m) { adj[ind[i][j]].push_back(ind[i + 1][j]); adj[ind[i + 1][j]].push_back(ind[i][j]); } if (j + 1 < n) { adj[ind[i][j]].push_back(ind[i][j + 1]); adj[ind[i][j + 1]].push_back(ind[i][j]); } } for (int i = 0; i < m * n; i++) { root[i] = i; sz[i] = 1; col[i] = -1; } for (int u = 0; u < m * n; u++) { int c; cin >> c; Color(u, c); } cin >> q; while (q--) { int x, y, c; cin >> x >> y >> c; x--, y--; Color(ind[x][y], c); } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) cout << col[FindRoot(ind[i][j])] << ' '; cout << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...