#include <cstdio> #include <cstdlib> #include <vector> struct ufind { ufind* parent = nullptr; int rank = 0; ufind* find() { if (parent == nullptr) { return this; } parent = parent->find(); return parent; } static void oonion(ufind& x, ufind& y) { ufind* xroot = x.find(); ufind* yroot = y.find(); if (xroot->rank > yroot->rank) { yroot->parent = xroot; } else if (xroot->rank < yroot->rank) { xroot->parent = yroot; } else if (xroot != yroot) { yroot->parent = xroot; xroot->rank = xroot->rank + 1; } } }; int colors[2 * 100 * 1000]; int color_positions[2 * 100 * 1000]; int main() { int n, k; scanf("%d %d", &n, &k); for (int i = 0; i < 2 * n; i += 2) { int x; scanf("%d", &x); colors[i] = x - 1; color_positions[x - 1] = i; } for (int i = 1; i < 2 * n; i += 2) { int x; scanf("%d", &x); colors[i] = x - 1; color_positions[x - 1] = i; } std::vector<int> interests(k + 1, 0); for (int begin_c = 0; begin_c < 2 * n; begin_c++) { std::vector<ufind> ufs(2 * n); int current_interest = 0; for (int end_c = begin_c; end_c < 2 * n; end_c++) { const int pos = color_positions[end_c]; const int nbs[3] = { pos ^ 1, (pos + 2) % (2 * n), (2 * n + pos - 2) % (2 * n), }; current_interest++; for (int i : nbs) { const int nb_color = colors[i]; if (nb_color < begin_c || end_c <= nb_color) { continue; } ufind* r1 = ufs[pos].find(); ufind* r2 = ufs[i].find(); if (r1 != r2) { ufind::oonion(*r1, *r2); current_interest--; } } if (current_interest < interests.size()) { interests[current_interest]++; } } } for (int i = 1; i <= k; i++) { printf("%d ", interests[i]); } putchar('\n'); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | #include <cstdio> #include <cstdlib> #include <vector> struct ufind { ufind* parent = nullptr; int rank = 0; ufind* find() { if (parent == nullptr) { return this; } parent = parent->find(); return parent; } static void oonion(ufind& x, ufind& y) { ufind* xroot = x.find(); ufind* yroot = y.find(); if (xroot->rank > yroot->rank) { yroot->parent = xroot; } else if (xroot->rank < yroot->rank) { xroot->parent = yroot; } else if (xroot != yroot) { yroot->parent = xroot; xroot->rank = xroot->rank + 1; } } }; int colors[2 * 100 * 1000]; int color_positions[2 * 100 * 1000]; int main() { int n, k; scanf("%d %d", &n, &k); for (int i = 0; i < 2 * n; i += 2) { int x; scanf("%d", &x); colors[i] = x - 1; color_positions[x - 1] = i; } for (int i = 1; i < 2 * n; i += 2) { int x; scanf("%d", &x); colors[i] = x - 1; color_positions[x - 1] = i; } std::vector<int> interests(k + 1, 0); for (int begin_c = 0; begin_c < 2 * n; begin_c++) { std::vector<ufind> ufs(2 * n); int current_interest = 0; for (int end_c = begin_c; end_c < 2 * n; end_c++) { const int pos = color_positions[end_c]; const int nbs[3] = { pos ^ 1, (pos + 2) % (2 * n), (2 * n + pos - 2) % (2 * n), }; current_interest++; for (int i : nbs) { const int nb_color = colors[i]; if (nb_color < begin_c || end_c <= nb_color) { continue; } ufind* r1 = ufs[pos].find(); ufind* r2 = ufs[i].find(); if (r1 != r2) { ufind::oonion(*r1, *r2); current_interest--; } } if (current_interest < interests.size()) { interests[current_interest]++; } } } for (int i = 1; i <= k; i++) { printf("%d ", interests[i]); } putchar('\n'); return 0; } |