Submission #577006

#TimeUsernameProblemLanguageResultExecution timeMemory
577006PurpleCrayonPaint (COI20_paint)C++17
100 / 100
1061 ms173532 KiB
#include <bits/stdc++.h> using namespace std; #define sz(v) int(v.size()) #define ar array typedef long long ll; const int N = 2e5+10, MOD = 998244353; const int B = 2e3; const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1}; int n, m, p[N], sz[N]; int col[N]; unordered_map<int, unordered_set<int>> adj_col[N]; int find_set(int v) { return v == p[v] ? v : p[v] = find_set(p[v]); } unordered_set<int> all_big; void union_sets(int a, int b) { // merge, but only in the dsu a = find_set(a), b = find_set(b); if (a == b) return; if (sz[a] < sz[b]) swap(a, b); p[b] = a, sz[a] += sz[b], sz[b] = 0; all_big.erase(b); } void union_big(int a, int b) { // just merge adj_col a = find_set(a), b = find_set(b); if (a == b) return; if (sz[a] < sz[b]) swap(a, b); for (auto& [k, v] : adj_col[b]) { for (auto& x : v) adj_col[a][k].insert(x); } adj_col[b].clear(); } int get_col(int v) { return col[find_set(v)]; } int tt = 0; int vis[N], use[N]; int que[N], ptr = 0; vector<int> small_adj; void dfs_small(int _v) { ptr = 0; que[ptr++] = _v; vis[_v] = tt; for (int rep = 0; rep < ptr; rep++) { int v = que[rep]; int i = v / m, j = v % m; for (int k = 0; k < 4; k++) { int ni = i + dx[k], nj = j + dy[k]; if (ni < 0 || ni >= n || nj < 0 || nj >= m) continue; if (vis[ni*m + nj] == tt) continue; if (find_set(ni*m + nj) != find_set(v)) { if (use[find_set(ni*m + nj)] != tt) { small_adj.push_back(find_set(ni*m + nj)); use[find_set(ni*m + nj)] = tt; } } else { que[ptr++] = ni*m + nj; vis[ni*m + nj] = tt; } } } } void make_big(int v, bool finished_dfs = false) { // make information for v to be a big component if (!finished_dfs) { tt++; small_adj.clear(); dfs_small(v); } all_big.insert(find_set(v)); for (auto nxt : small_adj) { adj_col[find_set(v)][get_col(nxt)].insert(find_set(nxt)); } } void add_small(int v) { // add v to the info of all surrounding big components tt++; small_adj.clear(); dfs_small(v); for (auto nxt : small_adj) { if (sz[find_set(nxt)] >= B) { adj_col[find_set(nxt)][get_col(v)].insert(find_set(v)); } } } void clear_comp(int v) { // remove v from the info of all surrounding big components for (auto nxt : all_big) { adj_col[nxt][get_col(v)].erase(find_set(v)); } } void upd_big(int v, int x) { v = find_set(v); auto to_merge = adj_col[v][x]; for (auto nxt : to_merge) { clear_comp(nxt); } clear_comp(v); for (auto nxt : to_merge) { if (sz[find_set(nxt)] < B) { make_big(nxt); } union_big(v, nxt); union_sets(v, nxt); } col[find_set(v)] = x; v = find_set(v); for (auto nxt : all_big) if (adj_col[v][get_col(nxt)].find(nxt) != adj_col[v][get_col(nxt)].end()) { adj_col[nxt][get_col(v)].insert(v); } } void upd_small(int v, int x) { tt++; small_adj.clear(); dfs_small(v); int new_size = sz[find_set(v)]; for (auto nxt : small_adj) if (get_col(nxt) == x) { new_size += sz[find_set(nxt)]; } if (new_size >= B) { make_big(v, true); upd_big(v, x); } else { for (auto nxt : small_adj) if (sz[find_set(nxt)] >= B) { adj_col[nxt][get_col(v)].erase(find_set(v)); } for (auto add : small_adj) { if (get_col(add) == x) { clear_comp(add); } } for (auto add : small_adj) { if (get_col(add) == x) { union_sets(v, add); } } col[find_set(v)] = x; add_small(v); } } void upd(int i, int j, int x) { int v = i*m + j; if (sz[find_set(v)] >= B) upd_big(v, x); else upd_small(v, x); } int a[N]; void init() { // initially merge stuff for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { p[i*m + j] = i*m + j; sz[i*m + j] = 1; } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> a[i*m + j]; col[i*m + j] = a[i*m + j]; } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { for (int k = 0; k < 4; k++) { int ni = i + dx[k], nj = j + dy[k]; if (ni < 0 || ni >= n || nj < 0 || nj >= m) continue; if (a[ni*m + nj] == a[i*m + j]) { union_sets(i*m + j, ni*m + nj); } } } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (p[i*m + j] == i*m + j && sz[find_set(i*m + j)] >= B) { make_big(i*m + j); } } } } void solve() { cin >> n >> m; init(); int q; cin >> q; while (q--) { int i, j, x; cin >> i >> j >> x, --i, --j; upd(i, j, x); } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) cout << col[find_set(i*m + j)] << ' '; cout << '\n'; } } int main() { ios::sync_with_stdio(false); cin.tie(0); int T = 1; // cin >> T; while (T--) solve(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...