Advertisement
cincout

Сжатие таблицы (открытка 2016)

Mar 19th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.36 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. const int sz = 1000005;
  6. int vis[sz], dp[sz];
  7. int p[sz], we[sz];
  8.  
  9. int get(int a)
  10. {
  11. if (p[a] == a)
  12. return a;
  13. return p[a] = get(p[a]);
  14. }
  15.  
  16. void unit(int a, int b)
  17. {
  18. a = get(a);
  19. b = get(b);
  20. if (a != b) {
  21. if (rand() & 1)
  22. p[a] = b;
  23. else
  24. p[b] = a;
  25. }
  26. }
  27.  
  28. vector <int> g[sz], rv[sz];
  29. vector <int> path;
  30. vector <vector<int>> a, ans, nxt;
  31. int n, m, t;
  32.  
  33. void dfs(int u)
  34. {
  35. vis[u] = 1;
  36. for (int v : g[u]) {
  37. if (vis[v] == 0) {
  38. dfs(v);
  39. }
  40. }
  41. path.push_back(u);
  42. }
  43.  
  44. void make()
  45. {
  46. for (int i = 0; i < n; ++i) {
  47. unordered_map <int, int> lst;
  48. for (int j = 0; j < m; ++j) {
  49. int lol = i * m + j;
  50. if (lst.count(a[i][j])) {
  51. unit(lol, lst[a[i][j]]);
  52. }
  53. lst[a[i][j]] = lol;
  54. }
  55. }
  56. for (int j = 0; j < m; ++j) {
  57. unordered_map <int, int> lst;
  58. for (int i = 0; i < n; ++i) {
  59. int lol = i * m + j;
  60. if (lst.count(a[i][j])) {
  61. unit(lol, lst[a[i][j]]);
  62. }
  63. lst[a[i][j]] = lol;
  64. }
  65. }
  66.  
  67. int src = 0;
  68.  
  69. for (int i = 0; i < n; ++i) {
  70. for (int j = 0; j < m; ++j) {
  71. int k = i * m + j;
  72. int r = get(k);
  73. if (we[r] == -1) {
  74. we[r] = src++;
  75. }
  76. nxt[i][j] = we[r];
  77. }
  78. }
  79.  
  80. t = src;
  81.  
  82. for (int i = 0; i < n; ++i) {
  83. vector <pair<int, int>> sf;
  84. for (int j = 0; j < m; ++j)
  85. sf.emplace_back(a[i][j], nxt[i][j]);
  86. sort(sf.begin(), sf.end());
  87. int pre = sf[0].second;
  88. for (int j = 1; j < m; ++j) {
  89. if (sf[j].second != pre) {
  90. g[pre].push_back(sf[j].second);
  91. rv[sf[j].second].push_back(pre);
  92. pre = sf[j].second;
  93. }
  94. }
  95. }
  96.  
  97. for (int j = 0; j < m; ++j) {
  98. vector <pair<int, int>> sf;
  99. for (int i = 0; i < n; ++i)
  100. sf.emplace_back(a[i][j], nxt[i][j]);
  101. sort(sf.begin(), sf.end());
  102. int pre = sf[0].second;
  103. for (int i = 1; i < n; ++i) {
  104. if (sf[i].second != pre) {
  105. g[pre].push_back(sf[i].second);
  106. rv[sf[i].second].push_back(pre);
  107. pre = sf[i].second;
  108. }
  109. }
  110. }
  111.  
  112. }
  113.  
  114.  
  115. int main()
  116. {
  117. ios::sync_with_stdio(false);
  118. cin.tie(nullptr);
  119.  
  120. fill(we, we + sz, -1);
  121.  
  122. for (int i = 0; i < sz; ++i)
  123. p[i] = i;
  124.  
  125. cin >> n >> m;
  126. a.resize(n, vector<int>(m)), ans.resize(n, vector<int>(m)), nxt.assign(n, vector<int>(m, -1));
  127.  
  128. for (int i = 0; i < n; ++i) {
  129. for (int j = 0; j < m; ++j) {
  130. cin >> a[i][j];
  131. }
  132. }
  133.  
  134. make();
  135.  
  136. for (int i = 0; i < t; ++i) {
  137. if (!vis[i]) {
  138. dfs(i);
  139. }
  140. }
  141. reverse(path.begin(), path.end());
  142.  
  143. for (int i = 0; i < t; ++i) {
  144. int cur = path[i];
  145. dp[cur] = 1;
  146. for (int j : rv[cur]) {
  147. dp[cur] = max(dp[cur], dp[j] + 1);
  148. }
  149. }
  150. for (int i = 0; i < n; ++i)
  151. for (int j = 0; j < m; ++j)
  152. cout << dp[nxt[i][j]] << " \n"[j == m - 1];
  153.  
  154. return 0;
  155. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement