Submission #1295598

#TimeUsernameProblemLanguageResultExecution timeMemory
1295598TymondPaint (COI20_paint)C++20
0 / 100
8 ms2872 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; #define fi first #define se second #define vi vector<int> #define vll vector<long long> #define pii pair<int, int> #define pll pair<long long, long long> #define pb push_back #define mp make_pair #define eb emplace_back #define all(x) (x).begin(), (x).end() #define sz(x) (int)(x).size() mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); mt19937_64 rng64(chrono::high_resolution_clock::now().time_since_epoch().count()); inline int rand(int l,int r){return uniform_int_distribution<int>(l, r)(rng);} inline ll rand(ll l,ll r){return uniform_int_distribution<ll>(l, r)(rng64);} #ifdef DEBUG auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";} auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif struct custom_hash { static uint64_t splitmix64(uint64_t x) { x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } }; struct pair_hash{ size_t operator()(const pair<int,int>&x)const{ return hash<long long>()(((long long)x.first)^(((long long)x.second)<<32)); } }; const int MAXN = 2e5 + 7; const int MAXK = 1e5 + 7; const int B = 1; int dx[4] = {0, 0, 1, -1}; int dy[4] = {1, -1, 0, 0}; vector<pii> pos[MAXN]; vi g[min(100, MAXN / B + 10)][MAXK]; int bigId[MAXN]; int col[MAXN]; int licznik[MAXN]; vector<vi> id; vector<vi> a; int n, m, Q; int k = 1; vi big = {}; vi toMerge; void bfs(int x, int y, int c, int kol){ id[x][y] = c; col[c] = kol; queue<pii> q; q.push(mp(x, y)); vi xdd = {}; toMerge.clear(); while(sz(q)){ pii curr = q.front(); q.pop(); x = curr.fi; y = curr.se; pos[c].pb(curr); for(int z = 0; z < 4; z++){ int nx = x + dx[z]; int ny = y + dy[z]; if(min(nx, ny) >= 0 && nx < n && ny < m){ if(a[nx][ny] == kol && id[nx][ny] == 0){ id[nx][ny] = id[x][y]; q.push(mp(nx, ny)); }else if(col[id[nx][ny]] != kol && id[nx][ny] != 0){ xdd.pb(id[nx][ny]); licznik[id[nx][ny]] = 1; }else if(col[id[nx][ny]] == kol && id[nx][ny] != id[x][y]){ toMerge.pb(id[nx][ny]); } } } } vector<pii> s = {}; for(auto ele : xdd){ if(licznik[ele]){ licznik[ele] = 0; s.pb(mp(col[ele], ele)); } } if(sz(pos[c]) >= B){ bigId[c] = sz(big); big.pb(c); for(auto ele : s){ g[bigId[c]][ele.fi].pb(ele.se); if(sz(pos[ele.se]) >= B){ g[bigId[ele.se]][kol].pb(c); } } }else{ for(auto ele : s){ if(sz(pos[ele.se]) >= B){ g[bigId[ele.se]][kol].pb(c); } } } } void calc(){ id.assign(n, vi(m, 0)); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ if(id[i][j] == 0){ pos[k].clear(); bfs(i, j, k, a[i][j]); k++; } } } k--; } bool mergedToBig; void merge(int id1, int id2){ if(sz(pos[id1]) < sz(pos[id2])){ swap(id1, id2); } if(sz(pos[id1]) >= B && sz(pos[id2]) >= B){ for(int j = 1; j <= MAXK; j++){ for(auto ele : g[bigId[id2]][j]){ if(col[ele] == j){ g[bigId[id1]][j].pb(ele); } } } } if(sz(pos[id1]) >= B){ mergedToBig = true; } for(auto ele : pos[id2]){ pos[id1].pb(ele); id[ele.fi][ele.se] = id1; } pos[id2].clear(); } void createBig(int x, int y, int cl){ bigId[id[x][y]] = sz(big); big.pb(id[x][y]); bfs(x, y, id[x][y], cl); for(auto ele : toMerge){ merge(id[x][y], ele); } } void updBig(int x, int y, int nc){ vi usu = {}; col[id[x][y]] = nc; for(int i = 0; i < sz(g[bigId[id[x][y]]][nc]); i++){ int now = g[bigId[id[x][y]]][nc][i]; // cerr << x << ' ' << y << ' ' << now << '\n'; // debug(pos[now]); // cerr << col[now] << ' ' << nc << '\n'; if(col[now] != nc){ usu.pb(i); continue; } merge(id[x][y], now); } for(auto ele : usu){ swap(g[bigId[id[x][y]]][nc][sz(g[bigId[id[x][y]]][nc]) - 1], g[bigId[id[x][y]]][nc][ele]); g[bigId[id[x][y]]][nc].pop_back(); } } void updSmall(int x, int y, int nc){ vector<pii> curr = pos[id[x][y]]; vector<pii> addG = {}; vi xdd = {}; mergedToBig = false; for(auto ele : curr){ for(int z = 0; z < 4; z++){ int j = id[x][y]; col[j] = nc; int nx = ele.fi + dx[z]; int ny = ele.se + dy[z]; if(min(nx, ny) >= 0 && nx < n && ny < m && id[nx][ny] != j && col[id[nx][ny]] == nc){ merge(j, id[nx][ny]); }else if(min(nx, ny) >= 0 && nx < n && ny < m && id[nx][ny] != j && col[id[nx][ny]] != nc){ xdd.pb(id[nx][ny]); licznik[id[nx][ny]] = 1; } } } for(auto ele : xdd){ if(licznik[ele]){ licznik[ele] = 0; addG.pb(mp(col[ele], ele)); } } if(sz(pos[id[x][y]]) >= B){ if(!mergedToBig){ createBig(x, y, nc); return; } for(auto ele : addG){ g[bigId[id[x][y]]][ele.fi].pb(ele.se); } } } int main(){ ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL); cin >> n >> m; a.assign(n, vi(m)); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ cin >> a[i][j]; } } calc(); // for(int i = 1; i <= k; i++){ // cerr << "----\n"; // cerr << i << ' ' << col[i] << '\n'; // debug(pos[i]); // } // cerr << "BIGGGG\n"; // for(auto ele : big){ // cerr << ele << '\n'; // for(int j = 0; j <= 3; j++){ // cerr << j << '\n'; // debug(g[bigId[ele]][j]); // } // cerr << "-----\n"; // } cin >> Q; for(int j = 1; j <= Q; j++){ int x, y, nc; cin >> x >> y >> nc; x--; y--; if(sz(pos[id[x][y]]) >= B){ updBig(x, y, nc); }else{ updSmall(x, y, nc); } vector<vi> ans(n, vi(m)); // cerr << "AFTER QUERY: " << j << '\n'; // for(int i = 1; i <= k; i++){ // for(auto ele : pos[i]){ // ans[ele.fi][ele.se] = col[i]; // } // } // for(int i = 0; i < n; i++){ // for(int j2 = 0; j2 < m; j2++){ // cout << ans[i][j2] << ' '; // } // cout << '\n'; // } // cerr << id[0][2] << '\n'; // debug(pos[id[0][2]]); } vector<vi> ans(n, vi(m)); for(int i = 1; i <= k; i++){ for(auto ele : pos[i]){ ans[ele.fi][ele.se] = col[i]; } } //cerr << "FINAL\n"; for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ cout << ans[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...