#include <bits/stdc++.h> using std::cin, std::cout; using std::string; using std::array; using std::vector; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; const char endl = '\n'; template<class num> inline num ceildiv(num a, num b) { return (a + b - 1) / b; } template<class num> inline num modulo(num i, num n) { //return value >= 0 const num k = i % n; return k < 0 ? k + n : k; } struct person { int dsu; int size = 1; bool sure = false; bool deleted = false; }; const int max_n = 300000 + 5; int dsuindex[max_n]; vector<person> people; void dsuinit() { for (int i = 0; i < max_n; i++) { dsuindex[i] = -1; } } int get_dsu_index(int i) { if (dsuindex[i] == -1) { int newindex = people.size(); people.push_back({ .dsu = newindex }); dsuindex[i] = newindex; } return dsuindex[i]; } int root(int i) { vector<int> for_compression; while (i != people[i].dsu) { for_compression.push_back(i); i = people[i].dsu; } for (int compressed : for_compression) { people[compressed].dsu = i; } return i; } // a computer is given to a or b, so their sets are united void unite(int a, int b) { a = get_dsu_index(a); b = get_dsu_index(b); a = root(a); b = root(b); if (a == b) { people[a].sure = true; return; } // make a the bigger one if (people[a].size < people[b].size) std::swap(a, b); people[b].dsu = a; if (people[b].sure) people[a].sure = true; people[a].size += people[b].size; } // person i's computer breaks void remove(int real_i) { int i = get_dsu_index(real_i); int r = root(i); people[r].size--; people[i].deleted = true; dsuindex[real_i] = -1; } int main() { std::ios_base::sync_with_stdio(0); cin.tie(NULL); dsuinit(); int n, q; cin >> n >> q; for (int qq = 0; qq < q; qq++) { char query_type; cin >> query_type; if (query_type == '+') { int a, b; cin >> a >> b; unite(a, b); } if (query_type == '-') { int a; cin >> a; remove(a); } if (query_type == '?') { int a; cin >> a; a = get_dsu_index(a); a = root(a); bool sure = people[a].sure; int size = people[a].size; if (sure) { cout << 1; } else { if (size == 1) { cout << 0; } else { cout << '?'; } } } } cout << endl; 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 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | #include <bits/stdc++.h> using std::cin, std::cout; using std::string; using std::array; using std::vector; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; const char endl = '\n'; template<class num> inline num ceildiv(num a, num b) { return (a + b - 1) / b; } template<class num> inline num modulo(num i, num n) { //return value >= 0 const num k = i % n; return k < 0 ? k + n : k; } struct person { int dsu; int size = 1; bool sure = false; bool deleted = false; }; const int max_n = 300000 + 5; int dsuindex[max_n]; vector<person> people; void dsuinit() { for (int i = 0; i < max_n; i++) { dsuindex[i] = -1; } } int get_dsu_index(int i) { if (dsuindex[i] == -1) { int newindex = people.size(); people.push_back({ .dsu = newindex }); dsuindex[i] = newindex; } return dsuindex[i]; } int root(int i) { vector<int> for_compression; while (i != people[i].dsu) { for_compression.push_back(i); i = people[i].dsu; } for (int compressed : for_compression) { people[compressed].dsu = i; } return i; } // a computer is given to a or b, so their sets are united void unite(int a, int b) { a = get_dsu_index(a); b = get_dsu_index(b); a = root(a); b = root(b); if (a == b) { people[a].sure = true; return; } // make a the bigger one if (people[a].size < people[b].size) std::swap(a, b); people[b].dsu = a; if (people[b].sure) people[a].sure = true; people[a].size += people[b].size; } // person i's computer breaks void remove(int real_i) { int i = get_dsu_index(real_i); int r = root(i); people[r].size--; people[i].deleted = true; dsuindex[real_i] = -1; } int main() { std::ios_base::sync_with_stdio(0); cin.tie(NULL); dsuinit(); int n, q; cin >> n >> q; for (int qq = 0; qq < q; qq++) { char query_type; cin >> query_type; if (query_type == '+') { int a, b; cin >> a >> b; unite(a, b); } if (query_type == '-') { int a; cin >> a; remove(a); } if (query_type == '?') { int a; cin >> a; a = get_dsu_index(a); a = root(a); bool sure = people[a].sure; int size = people[a].size; if (sure) { cout << 1; } else { if (size == 1) { cout << 0; } else { cout << '?'; } } } } cout << endl; return 0; } |