#include <iostream> #include <string> #include <algorithm> #include <vector> using namespace std; struct DisjointSetUnion { vector<int> root; vector<int> size; vector<int> vacant; vector<vector<int>> G; explicit DisjointSetUnion(int n) : root(vector<int>(n)), size(vector<int>(n)), vacant(vector<int>(n)), G(vector<vector<int>>(n)) { for (int i = 0; i < n; ++i) { root[i] = i; size[i] = 1; } } int find(int v) { if (root[v] != v) root[v] = find(root[v]); return root[v]; } void join(int a, int b) { if (size[a] < size[b]) swap(a, b); G[a].push_back(b); root[b] = a; size[a] += size[b]; vacant[a] += vacant[b]; } void traverse(int v, bool flag, vector<int> &map, vector<int> &node, vector<bool> &status) { node[map[v]] = 0; status[map[v]] = flag; map[v] = 0; for (int u : G[v]) traverse(u, flag, map, node, status); } void vacate(int v, vector<int> &map, vector<int> &node, vector<bool> &status) { ++vacant[v]; if (size[v] > vacant[v] + 1) return; traverse(v, false, map, node, status); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; vector<int> node(n + 1); vector<bool> status(n + 1); vector<int> map(n + 2 * q + 1); DisjointSetUnion U(n + 2 * q + 1); int w = 1; char op; int a, b; while (q--) { cin >> op >> a; if (op == '+') { cin >> b; if (status[a]) a = b; if (status[b]) b = a; if (!node[a]) { node[a] = w; map[w++] = a; } if (!node[b]) { node[b] = w; map[w++] = b; } int r = U.find(node[a]); int s = U.find(node[b]); if (r == s) U.traverse(r, true, map, node, status); else U.join(r, s); } else if (op == '-') { if (node[a]) { int r = U.find(node[a]); U.vacate(r, map, node, status); } map[node[a]] = 0; node[a] = 0; status[a] = false; } else { if (status[a]) cout << '1'; else if (node[a]) cout << '?'; else cout << '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 | #include <iostream> #include <string> #include <algorithm> #include <vector> using namespace std; struct DisjointSetUnion { vector<int> root; vector<int> size; vector<int> vacant; vector<vector<int>> G; explicit DisjointSetUnion(int n) : root(vector<int>(n)), size(vector<int>(n)), vacant(vector<int>(n)), G(vector<vector<int>>(n)) { for (int i = 0; i < n; ++i) { root[i] = i; size[i] = 1; } } int find(int v) { if (root[v] != v) root[v] = find(root[v]); return root[v]; } void join(int a, int b) { if (size[a] < size[b]) swap(a, b); G[a].push_back(b); root[b] = a; size[a] += size[b]; vacant[a] += vacant[b]; } void traverse(int v, bool flag, vector<int> &map, vector<int> &node, vector<bool> &status) { node[map[v]] = 0; status[map[v]] = flag; map[v] = 0; for (int u : G[v]) traverse(u, flag, map, node, status); } void vacate(int v, vector<int> &map, vector<int> &node, vector<bool> &status) { ++vacant[v]; if (size[v] > vacant[v] + 1) return; traverse(v, false, map, node, status); } }; int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; vector<int> node(n + 1); vector<bool> status(n + 1); vector<int> map(n + 2 * q + 1); DisjointSetUnion U(n + 2 * q + 1); int w = 1; char op; int a, b; while (q--) { cin >> op >> a; if (op == '+') { cin >> b; if (status[a]) a = b; if (status[b]) b = a; if (!node[a]) { node[a] = w; map[w++] = a; } if (!node[b]) { node[b] = w; map[w++] = b; } int r = U.find(node[a]); int s = U.find(node[b]); if (r == s) U.traverse(r, true, map, node, status); else U.join(r, s); } else if (op == '-') { if (node[a]) { int r = U.find(node[a]); U.vacate(r, map, node, status); } map[node[a]] = 0; node[a] = 0; status[a] = false; } else { if (status[a]) cout << '1'; else if (node[a]) cout << '?'; else cout << '0'; } } } |