제출 #393398

#제출 시각아이디문제언어결과실행 시간메모리
393398VEGAnnPaint (COI20_paint)C++14
69 / 100
3047 ms38812 KiB
#include <bits/stdc++.h> #define ft first #define sd second #define PB push_back #define sz(x) ((int)x.size()) #define i2 array<int,2> using namespace std; const int N = 200100; const int BLOCK = 1500; vector<i2> elms; bool init_mrk[N]; int n, m, pre[N]; int c[N], who[N]; int used[N], tt = 0; int stp[4][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}}; struct comp{ int color; vector<i2> pnts; vector<int> big_neib; bool large; map<int, vector<int> > by_color; }; vector<comp> comps; int get_pre(int x) { return (pre[x] == x ? x : pre[x] = get_pre(pre[x])); } void init_dfs(int x, int y, int now){ if (x < 0 || y < 0 || x >= n || y >= m) return; if (init_mrk[x * m + y]) return; if (c[x * m + y] != now) return; elms.PB({x, y}); init_mrk[x * m + y] = 1; who[x * m + y] = sz(comps); for (int it = 0; it < 4; it++){ int cx = x + stp[it][0]; int cy = y + stp[it][1]; init_dfs(cx, cy, now); } } void declare_big(comp &now){ now.large = 1; tt++; for (i2 CR : now.pnts){ int x = CR[0], y = CR[1]; int cur_comp = who[x * m + y]; for (int it = 0; it < 4; it++){ int cx = x + stp[it][0]; int cy = y + stp[it][1]; if (cx < 0 || cy < 0 || cx >= n || cy >= m) continue; int co_id = who[cx * m + cy]; if (used[co_id] < tt){ used[co_id] = tt; comps[co_id].big_neib.PB(cur_comp); comps[cur_comp].by_color[comps[co_id].color].PB(co_id); } } } } void Init(){ cin >> n >> m; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) cin >> c[i * m + j]; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++){ if (init_mrk[i * m + j]) continue; elms.clear(); init_dfs(i, j, c[i * m + j]); comp new_comp; new_comp.color = c[i * m + j]; new_comp.pnts = elms; new_comp.large = 0; new_comp.big_neib.clear(); new_comp.by_color.clear(); comps.PB(new_comp); } for (int i = 0; i < n * m; i++) pre[i] = i; for (int i = 0; i < sz(comps); i++) if (sz(comps[i].pnts) > BLOCK) declare_big(comps[i]); } void merge(int c1, int c2){ c1 = get_pre(c1); c2 = get_pre(c2); assert(c1 != c2); if (sz(comps[c1].pnts) < sz(comps[c2].pnts)) swap(c1, c2); comp &fi = comps[c1]; comp &se = comps[c2]; if (fi.large && !se.large) declare_big(se); if (se.large && !fi.large) declare_big(fi); { /// update pnts pre[c2] = c1; for (i2 CR : se.pnts){ int x = CR[0], y = CR[1]; fi.pnts.PB(CR); who[x * m + y] = c1; } vector<i2> ().swap(se.pnts); } { /// update big_neib vector<int> nw_big; nw_big.clear(); tt++; for (int cr : fi.big_neib){ cr = get_pre(cr); if (used[cr] < tt) { nw_big.PB(cr); used[cr] = tt; } } for (int cr : se.big_neib){ cr = get_pre(cr); if (used[cr] < tt) { nw_big.PB(cr); used[cr] = tt; } } vector<int> ().swap(fi.big_neib); vector<int> ().swap(se.big_neib); fi.big_neib.swap(nw_big); } if (fi.large) { /// update by_color if (sz(fi.by_color) < sz(se.by_color)) fi.by_color.swap(se.by_color); for (auto cr : se.by_color){ int col = cr.ft; vector<int> &sml = cr.sd; vector<int> &big = fi.by_color[col]; if (sz(sml) > sz(big)) sml.swap(big); for (int cr : sml) big.PB(cr); } se.by_color.clear(); } if (!fi.large && sz(fi.pnts) > BLOCK) declare_big(fi); } void Fill(int x, int y, int nw_col){ int cur_comp = who[x * m + y]; comps[cur_comp].color = nw_col; if (sz(comps[cur_comp].pnts) > BLOCK){ tt++; vector<int> nw; nw.clear(); used[cur_comp] = tt; for (int co_id : comps[cur_comp].by_color[nw_col]){ co_id = get_pre(co_id); if (used[co_id] < tt && comps[co_id].color == nw_col){ nw.PB(co_id); used[co_id] = tt; } } for (int ids : nw) merge(cur_comp, ids); } else { tt++; vector<int> nw; nw.clear(); used[cur_comp] = tt; for (i2 CR : comps[cur_comp].pnts){ int X = CR[0], Y = CR[1]; for (int it = 0; it < 4; it++){ int cx = X + stp[it][0]; int cy = Y + stp[it][1]; if (cx < 0 || cy < 0 || cx >= n || cy >= m) continue; int co_id = who[cx * m + cy]; if (used[co_id] < tt && comps[co_id].color == nw_col){ nw.PB(co_id); used[co_id] = tt; } } } for (int ids : nw) merge(cur_comp, ids); } /// traverse big_neib and change color cur_comp = who[x * m + y]; int col = comps[cur_comp].color; tt++; for (int cr : comps[cur_comp].big_neib){ cr = get_pre(cr); if (used[cr] < tt) { comps[cr].by_color[col].PB(cur_comp); used[cr] = tt; } } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); #ifdef _LOCAL freopen("in.txt","r",stdin); #endif // _LOCAL Init(); int qq; cin >> qq; for (; qq; qq--){ int x, y, col; cin >> x >> y >> col; x--; y--; Fill(x, y, col); } for (int i = 0; i < n; i++){ for (int j = 0; j < m; j++){ int co_id = who[i * m + j]; cout << comps[co_id].color << " "; } 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...