Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include "bits/stdc++.h"
- using namespace std;
- #define all(a) a.begin(), a.end()
- #define int long long
- using namespace std;
- mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
- struct Dsu {
- vector<int> p, siz, mx;
- Dsu(int n) {
- p.resize(n); siz.resize(n, 1);
- for (int i = 0; i < n; i++) {
- p[i] = i;
- }
- }
- int find(int v) {
- if (v == p[v]) {
- return v;
- }
- return p[v] = find(p[v]);
- }
- void merge(int a, int b) {
- a = find(a), b = find(b);
- if (a == b) {
- return;
- }
- if (siz[a] < siz[b]) {
- swap(a, b);
- }
- p[b] = a;
- siz[a] += siz[b];
- }
- };
- signed main() {
- #ifdef _DEBUG
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- int n, m; cin >> n >> m;
- vector<vector<int>> a(n, vector<int>(m));
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- cin >> a[i][j];
- }
- }
- Dsu U(n * m);
- for (int i = 0; i < n; i++) {
- unordered_map<int, int> lst;
- for (int j = 0; j < m; j++) {
- int pos = i * m + j;
- if (lst.find(a[i][j]) != lst.end()) {
- U.merge(lst[a[i][j]], pos);
- }
- lst[a[i][j]] = pos;
- }
- }
- for (int j = 0; j < m; j++) {
- unordered_map<int, int> lst;
- for (int i = 0; i < n; i++) {
- int pos = i * m + j;
- if (lst.find(a[i][j]) != lst.end()) {
- U.merge(lst[a[i][j]], pos);
- }
- lst[a[i][j]] = pos;
- }
- }
- vector<int> pw(n * m);
- vector<vector<int>> gr(n * m);
- for (int i = 0; i < n; i++) {
- vector<pair<int, int>> nw;
- for (int j = 0; j < m; j++) {
- int pos = i * m + j;
- nw.push_back({ a[i][j], pos });
- }
- sort(all(nw));
- for (int j = 0; j + 1 < m; j++) {
- if (nw[j].first == nw[j + 1].first) { continue; }
- int a = U.find(nw[j].second), b = U.find(nw[j + 1].second);
- gr[a].push_back(b);
- pw[b]++;
- }
- }
- for (int j = 0; j < m; j++) {
- vector<pair<int, int>> nw;
- for (int i = 0; i < n; i++) {
- int pos = i * m + j;
- nw.push_back({ a[i][j], pos });
- }
- sort(all(nw));
- for (int i = 0; i + 1 < n; i++) {
- if (nw[i].first == nw[i + 1].first) { continue; }
- int a = U.find(nw[i].second), b = U.find(nw[i + 1].second);
- gr[a].push_back(b);
- pw[b]++;
- }
- }
- vector<bool> used(n * m, false);
- vector<int> res(n * m);
- queue<int> q;
- for (int i = 0; i < n * m; i++) {
- if (!pw[U.find(i)] && !used[U.find(i)]) {
- int x = U.find(i);
- q.push(x);
- used[x] = true;
- res[x] = 1;
- }
- }
- while (!q.empty()) {
- int v = q.front();
- q.pop();
- for (int& u : gr[v]) {
- res[u] = max(res[v] + 1, res[u]);
- pw[u]--;
- if (!pw[u]) {
- q.push(u);
- }
- }
- }
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- int pos = U.find(i * m + j);
- cout << res[pos] << ' ';
- }
- cout << '\n';
- }
- }
Advertisement