/** * Patryk Kisielewski * * Potyczki Algorytmiczne 2024 * Zadanie: MOD - Modernizacja Bajtocji [A] */ #include <cstdio> #include <iostream> #include <set> #include <utility> #include <vector> using namespace std; struct Item { Item() : root(this), count(1), deleted(false) {} Item* root; long long count; bool deleted; }; int n, q; vector<Item*> sets; Item* findRoot(Item* item) { Item* root = item->root; if (root == item) { return root; } item->root = findRoot(item->root); return item->root; } inline void merge(Item* root_a, Item* root_b) { root_b->root = root_a; root_a->count += root_b->count; } void remove(int a, bool deleted = false) { Item* root = findRoot(sets[a]); root->count -= 1; if (deleted) { root->deleted = true; } sets[a] = new Item(); sets[a]->deleted = deleted; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> q; sets = vector<Item*>(n+1, nullptr); for (int i = 1; i <= n; ++i) { sets[i] = new Item(); } for (int i = 0; i < q; ++i) { char type; int a, b; cin >> type >> a; if (type == '?') { Item* root = findRoot(sets[a]); if (root->deleted) { cout << '1'; } else if (root->count == 1) { cout << '0'; } else { cout << '?'; } } else if (type == '+') { cin >> b; if (a == b) { remove(a, true); } else { Item* root_a = findRoot(sets[a]); Item* root_b = findRoot(sets[b]); if (root_a == root_b) { root_a->deleted = true; } else { if (root_a->deleted) { root_b->deleted = true; } else if (root_b->deleted) { root_a->deleted = true; } else { merge(root_a, root_b); } } } } else { // '-' remove(a); } } cout << '\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 95 96 97 98 99 100 101 102 103 104 | /** * Patryk Kisielewski * * Potyczki Algorytmiczne 2024 * Zadanie: MOD - Modernizacja Bajtocji [A] */ #include <cstdio> #include <iostream> #include <set> #include <utility> #include <vector> using namespace std; struct Item { Item() : root(this), count(1), deleted(false) {} Item* root; long long count; bool deleted; }; int n, q; vector<Item*> sets; Item* findRoot(Item* item) { Item* root = item->root; if (root == item) { return root; } item->root = findRoot(item->root); return item->root; } inline void merge(Item* root_a, Item* root_b) { root_b->root = root_a; root_a->count += root_b->count; } void remove(int a, bool deleted = false) { Item* root = findRoot(sets[a]); root->count -= 1; if (deleted) { root->deleted = true; } sets[a] = new Item(); sets[a]->deleted = deleted; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> q; sets = vector<Item*>(n+1, nullptr); for (int i = 1; i <= n; ++i) { sets[i] = new Item(); } for (int i = 0; i < q; ++i) { char type; int a, b; cin >> type >> a; if (type == '?') { Item* root = findRoot(sets[a]); if (root->deleted) { cout << '1'; } else if (root->count == 1) { cout << '0'; } else { cout << '?'; } } else if (type == '+') { cin >> b; if (a == b) { remove(a, true); } else { Item* root_a = findRoot(sets[a]); Item* root_b = findRoot(sets[b]); if (root_a == root_b) { root_a->deleted = true; } else { if (root_a->deleted) { root_b->deleted = true; } else if (root_b->deleted) { root_a->deleted = true; } else { merge(root_a, root_b); } } } } else { // '-' remove(a); } } cout << '\n'; return 0; } |