#include <bits/stdc++.h>
using namespace std;
vector<int> sub, isHeavy, cor, pai;
vector<unordered_set<int>> grafoLight;
vector<vector<unordered_set<int>>> grafoHeavy;
unordered_set<int> idHeavies;
const int MAXV = 1e5;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int R, S;
int T;
int find(int v) {return pai[v] = (v == pai[v] ? v : find(pai[v]));}
void une(int x, int y)
{
x = find(x); y = find(y);
if (x == y) return;
// cerr << "une " << x << " (" << x/S << ", " << x%S << ") and " << y << " (" << y/S << ", " << y%S << ")" << '\n';
if (sub[x] < sub[y]) swap(sub[x], sub[y]);
pai[y] = x; sub[x] += sub[y];
if (grafoLight[x].size() < grafoLight[y].size()) swap(grafoLight[x], grafoLight[y]);
for (auto viz : grafoLight[y]) grafoLight[x].insert(viz);
if (isHeavy[x] && isHeavy[y])
{
for (int c = 0; c < MAXV; c++)
for (auto viz : grafoHeavy[y][c])
grafoHeavy[x][c].insert(viz);
grafoHeavy[y].clear();
idHeavies.erase(y);
}
else if (isHeavy[x])
{
for (auto viz : grafoLight[y]) if (cor[find(viz)] != cor[x]) grafoHeavy[x][cor[viz]].insert(viz);
}
else if (isHeavy[y])
{
isHeavy[x] = 1;
swap(grafoHeavy[x], grafoHeavy[y]);
for (auto viz : grafoLight[x]) if (cor[find(viz)] != cor[x]) grafoHeavy[x][cor[viz]].insert(viz);
idHeavies.insert(x); idHeavies.erase(y);
}
else if (grafoLight[x].size() > T)
{
isHeavy[x] = 1;
idHeavies.insert(x);
grafoHeavy[x].resize(MAXV);
for (auto viz : grafoLight[x]) if (cor[find(viz)] != cor[x]) grafoHeavy[x][cor[viz]].insert(viz);
}
grafoLight[y].clear();
}
int getId(int x, int y) {return x*S + y;}
void getUnion(int i, int j, int C = -1)
{
// cerr << "||" << getId(i, j) << " (" << i << ", " << j << ")" << '\n';
int id = find(getId(i, j));
int lastC = cor[id];
if (C != -1) cor[id] = C;
else C = cor[id];
if (isHeavy[id])
{
// cerr << "\tHeavy" << '\n';
while (!grafoHeavy[id][cor[id]].empty())
{
auto it = grafoHeavy[id][cor[id]].begin();
int x = *it; grafoHeavy[id][cor[id]].erase(it);
x = find(x);
if (cor[x] == cor[id]) une(id, x);
}
}
else
{
// cerr << "\tLight" << '\n';
vector<int> viz;
for (auto x : grafoLight[id]) if (cor[find(x)] == cor[id]) viz.push_back(find(x));
for (auto x : viz) une(id, x);
// id = find(id); cerr << "new id: " << id << '\n';
}
id = find(id);
if (!isHeavy[id])
{
for (auto x : grafoLight[id])
{
if (isHeavy[find(x)])
{
// cerr << "x: " << find(x) << '\n';
grafoHeavy[find(x)][lastC].erase(id), grafoHeavy[find(x)][C].insert(id);
}
}
}
else
{
for (auto x : idHeavies)
{
if (x != id && grafoLight[x].count(id))
grafoHeavy[x][lastC].erase(id), grafoHeavy[x][C].insert(id);
}
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> R >> S;
vector<vector<int>> mat(R, vector<int>(S));
for (auto &x : mat)
for (auto &y : x)
cin >> y;
T = sqrt(3*R*S)+1;
pai.resize(R*S); iota(pai.begin(), pai.end(), 0);
sub.resize(R*S); fill(sub.begin(), sub.end(), 1);
isHeavy.resize(R*S, 0);
cor.resize(R*S); for (int i = 0; i < R; i++) for (int j = 0; j < S; j++) cor[getId(i, j)] = mat[i][j];
grafoLight.resize(R*S); grafoHeavy.resize(R*S);
for (int i = 0; i < R; i++)
for (int j = 0; j < S; j++)
{
for (int k = 0; k < 4; k++)
{
int hx = i + dx[k];
int hy = j + dy[k];
if (hx < 0 || hx >= R || hy < 0 || hy >= S) continue;
grafoLight[getId(i, j)].insert(getId(hx, hy));
}
}
for (int i = 0; i < R; i++)
for (int j = 0; j < S; j++)
{
getUnion(i, j);
}
// for (int i = 0; i < R; i++) for (int j = 0; j < S; j++) mat[i][j] = cor[find(getId(i, j))];
// cerr << "mat: " << '\n';
// for (auto &x : mat)
// {
// for (auto y : x)
// cerr << y << " ";
// cerr << '\n';
// }
// cerr << "Start queries" << '\n';
int Q; cin >> Q;
while (Q--)
{
int X, Y, C;
cin >> X >> Y >> C;
--X, --Y;
getUnion(X, Y, C);
}
for (int i = 0; i < R; i++) for (int j = 0; j < S; j++) mat[i][j] = cor[find(getId(i, j))];
for (auto &x : mat)
{
for (auto y : x)
cout << y << " ";
cout << '\n';
}
}
Compilation message
paint.cpp: In function 'void une(int, int)':
paint.cpp:42:32: warning: comparison of integer expressions of different signedness: 'std::unordered_set<int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
42 | else if (grafoLight[x].size() > T)
| ~~~~~~~~~~~~~~~~~~~~~^~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
600 KB |
Output is correct |
2 |
Correct |
3 ms |
6448 KB |
Output is correct |
3 |
Correct |
5 ms |
3676 KB |
Output is correct |
4 |
Incorrect |
15 ms |
19704 KB |
Output isn't correct |
5 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
60 ms |
13972 KB |
Output is correct |
2 |
Incorrect |
393 ms |
364232 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
266 ms |
99016 KB |
Output is correct |
2 |
Correct |
214 ms |
97228 KB |
Output is correct |
3 |
Correct |
286 ms |
138020 KB |
Output is correct |
4 |
Correct |
455 ms |
263716 KB |
Output is correct |
5 |
Correct |
353 ms |
240836 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
189 ms |
67156 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |