#include #include #include #include #include #include #include #include #include #include using namespace std; class UnionFindTree{ typedef struct { int parent; int rank; }base_node; vector node; public: UnionFindTree(int n){ node.resize(n); for(int i=0; i node[y].rank){ node[y].parent = x; }else{ node[x].rank++; unite(x,y); } } }; int dx[] = {0,0,1,-1,0,0}; int* dy = dx+2; #include int main(){ auto start = clock(); int h,w; cin >> h >> w; vector> A(h, vector(w)); for(int i=0; i> A[i][j]; } } UnionFindTree uft(h*w); for(int i=0; i=h || c<0 || c>=w) continue; if(A[i][j] == A[r][c]) uft.unite(i*w + j, r*w + c); } } } vector visit(h*w, false); vector> adj(h*w); for(int i=0; i q; q.push(root); visit[root] = true; while(q.size()){ int pos = q.front(); q.pop(); int r = pos/w; int c = pos%w; for(int k=0; k<4; k++){ int r_ = r+dy[k]; int c_ = c+dx[k]; if(r_<0 || r_>=h || c_<0 || c_>=w) continue; if(A[r][c] != A[r_][c_]){ adj[root].push_back(uft.find(r_*w + c_)); }else if(visit[r_*w + c_]==false){ visit[r_*w + c_] = true; q.push(r_*w + c_); } } } } int q; cin >> q; for(int i=0; i> r >> c >> x; r--; c--; int root = uft.find(r*w + c); r = root/w; c = root%w; if(A[r][c] == x) continue; A[r][c] = x; vector next_adj; for(int j: adj[root]){ int j_ = uft.find(j); for(int k:adj[j_]){ if(uft.same(k, root)) continue; next_adj.push_back(k); } } for(auto j: adj[root]){ uft.unite(root, j); } for(int j: adj[root]){ int j_ = uft.find(j); adj[j].resize(0); } adj[root].resize(0); sort(next_adj.begin(), next_adj.end()); next_adj.erase( unique(next_adj.begin(), next_adj.end()), next_adj.end()); root = uft.find(root); adj[root].resize(0); for(auto j:next_adj){ if(uft.same(j, root)) continue; adj[root].push_back(j); } swap(next_adj, adj[root]); } for(int i=0; i