#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <cassert>
using namespace std;
const int N = 3e5 + 7;
const int NN = 1e6 + 7;
vector<vector<int>> grupy;
int dsurep[NN], ile[NN], fancyrep[N], ilekomp[NN];
int find(int a) {
if (dsurep[a] == a)
return a;
return dsurep[a] = find(dsurep[a]);
}
int onion(int a, int b) {
a = find(a);
b = find(b);
if (a == b) {
ilekomp[a]++;
return a;
}
if (ile[a] < ile[b]) {
swap(a, b);
}
dsurep[b] = a;
ile[a] += ile[b];
ilekomp[a] += ilekomp[b] + 1;
grupy[a].insert(grupy[a].end(), grupy[b].begin(), grupy[b].end());
return a;
}
void disjoin(int r) {
assert(find(r) == r);
for (auto it : grupy[r]) {
dsurep[it] = it;
ilekomp[it] = 1;
ile[it] = 1;
if (it != r) {
grupy[it].clear();
grupy[it].push_back(it);
}
}
grupy[r].clear();
grupy[r].push_back(r);
}
int remove(int a) {
int r = find(a);
if (ile[r] == 1) {
ilekomp[a] = 0;
return a;
} else {
ilekomp[r]--;
ile[r]--;
int nextfancy = grupy.size();
grupy.emplace_back();
grupy[nextfancy].push_back(nextfancy);
dsurep[nextfancy] = nextfancy;
ile[nextfancy] = 1;
return nextfancy;
}
}
int main() {
int n, q;
cin >> n >> q;
grupy.emplace_back();
for (int i = 1; i <= n; i++) {
fancyrep[i] = i;
dsurep[i] = i;
ile[i] = 1;
grupy.emplace_back();
grupy[i].push_back(i);
}
string rodzaj;
int x, y;
while (q--) {
cin >> rodzaj;
if (rodzaj == "+") {
cin >> x >> y;
x = fancyrep[x];
y = fancyrep[y];
int r = onion(x, y);
if (ilekomp[r] == ile[r]) {
disjoin(r);
}
} else if (rodzaj == "-") {
cin >> x;
int fr = fancyrep[x];
int nfr = remove(fr);
fancyrep[x] = nfr;
} else {
cin >> x;
x = fancyrep[x];
x = find(x);
if (ilekomp[x] == 0)
cout << 0;
else if (ilekomp[x] == ile[x])
cout << 1;
else
cout << "?";
}
}
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 | #include <iostream> #include <vector> #include <algorithm> #include <set> #include <cassert> using namespace std; const int N = 3e5 + 7; const int NN = 1e6 + 7; vector<vector<int>> grupy; int dsurep[NN], ile[NN], fancyrep[N], ilekomp[NN]; int find(int a) { if (dsurep[a] == a) return a; return dsurep[a] = find(dsurep[a]); } int onion(int a, int b) { a = find(a); b = find(b); if (a == b) { ilekomp[a]++; return a; } if (ile[a] < ile[b]) { swap(a, b); } dsurep[b] = a; ile[a] += ile[b]; ilekomp[a] += ilekomp[b] + 1; grupy[a].insert(grupy[a].end(), grupy[b].begin(), grupy[b].end()); return a; } void disjoin(int r) { assert(find(r) == r); for (auto it : grupy[r]) { dsurep[it] = it; ilekomp[it] = 1; ile[it] = 1; if (it != r) { grupy[it].clear(); grupy[it].push_back(it); } } grupy[r].clear(); grupy[r].push_back(r); } int remove(int a) { int r = find(a); if (ile[r] == 1) { ilekomp[a] = 0; return a; } else { ilekomp[r]--; ile[r]--; int nextfancy = grupy.size(); grupy.emplace_back(); grupy[nextfancy].push_back(nextfancy); dsurep[nextfancy] = nextfancy; ile[nextfancy] = 1; return nextfancy; } } int main() { int n, q; cin >> n >> q; grupy.emplace_back(); for (int i = 1; i <= n; i++) { fancyrep[i] = i; dsurep[i] = i; ile[i] = 1; grupy.emplace_back(); grupy[i].push_back(i); } string rodzaj; int x, y; while (q--) { cin >> rodzaj; if (rodzaj == "+") { cin >> x >> y; x = fancyrep[x]; y = fancyrep[y]; int r = onion(x, y); if (ilekomp[r] == ile[r]) { disjoin(r); } } else if (rodzaj == "-") { cin >> x; int fr = fancyrep[x]; int nfr = remove(fr); fancyrep[x] = nfr; } else { cin >> x; x = fancyrep[x]; x = find(x); if (ilekomp[x] == 0) cout << 0; else if (ilekomp[x] == ile[x]) cout << 1; else cout << "?"; } } return 0; } |
English