#include <iostream>
#include <vector>
constexpr int maxn = 3e5 + 7, maxnq = 2e6 + 7;
int n, q;
bool musiMiec[maxnq], musiNieMiec[maxnq];
int rep[maxnq], newNumber[maxn], cntTaken[maxnq], members[maxnq];
std::vector<int> graf[maxn * 4];
void init() {
for(int i = 1; i <= n; i++) {
newNumber[i] = i;
rep[i] = i;
musiNieMiec[i] = true;
members[i] = 1;
}
}
int fuFind(int x) {
if(rep[x] == x)
return x;
rep[x] = fuFind(rep[x]);
return rep[x];
}
void fuUnion(int x, int y) {
x = fuFind(x); y = fuFind(y);
if(x == y)
return;
rep[x] = y;
members[y] += members[x];
cntTaken[y] += cntTaken[x];
}
void chk(int v) {
if(cntTaken[fuFind(v)] + 1 != members[fuFind(v)] || musiNieMiec[v] || musiMiec[v])
return;
musiNieMiec[v] = true;
musiMiec[v] = false;
graf[v].clear();
rep[v] = v;
members[v] = 1;
cntTaken[v] = 0;
}
void daj(int v) {
rep[v] = v;
musiMiec[v] = true;
musiNieMiec[v] = false;
for(const auto& u : graf[v]) {
if(rep[u] == u)
continue;
daj(u);
}
graf[v].clear();
}
void add(int a, int b) {
chk(a); chk(b);
if(fuFind(a) == fuFind(b) || musiMiec[b]) {
daj(fuFind(a));
}
if(musiMiec[a]) {
daj(fuFind(b));
}
musiNieMiec[a] = false;
musiNieMiec[b] = false;
graf[a].push_back(b);
graf[b].push_back(a);
fuUnion(a, b);
}
void query(int v) {
chk(v);
printf(musiMiec[v] ? "1" : musiNieMiec[v] ? "0" : "?");
}
void take(int v) {
auto vv = newNumber[v];
cntTaken[fuFind(vv)]++;
musiNieMiec[vv] = true;
musiMiec[vv] = false;
newNumber[v] = ++n;
musiNieMiec[n] = true;
musiMiec[n] = false;
rep[n] = n;
members[n] = 1;
}
int main() {
scanf("%d%d", &n, &q);
init();
char c;
int a, b;
for(int i = 0; i < q; i++) {
scanf(" %c", &c);
if(c == '+') {
scanf("%d%d", &a, &b);
add(newNumber[a], newNumber[b]);
}
if(c == '-') {
scanf("%d", &a);
take(a);
}
if(c == '?') {
scanf("%d", &a);
query(newNumber[a]);
}
}
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 | #include <iostream> #include <vector> constexpr int maxn = 3e5 + 7, maxnq = 2e6 + 7; int n, q; bool musiMiec[maxnq], musiNieMiec[maxnq]; int rep[maxnq], newNumber[maxn], cntTaken[maxnq], members[maxnq]; std::vector<int> graf[maxn * 4]; void init() { for(int i = 1; i <= n; i++) { newNumber[i] = i; rep[i] = i; musiNieMiec[i] = true; members[i] = 1; } } int fuFind(int x) { if(rep[x] == x) return x; rep[x] = fuFind(rep[x]); return rep[x]; } void fuUnion(int x, int y) { x = fuFind(x); y = fuFind(y); if(x == y) return; rep[x] = y; members[y] += members[x]; cntTaken[y] += cntTaken[x]; } void chk(int v) { if(cntTaken[fuFind(v)] + 1 != members[fuFind(v)] || musiNieMiec[v] || musiMiec[v]) return; musiNieMiec[v] = true; musiMiec[v] = false; graf[v].clear(); rep[v] = v; members[v] = 1; cntTaken[v] = 0; } void daj(int v) { rep[v] = v; musiMiec[v] = true; musiNieMiec[v] = false; for(const auto& u : graf[v]) { if(rep[u] == u) continue; daj(u); } graf[v].clear(); } void add(int a, int b) { chk(a); chk(b); if(fuFind(a) == fuFind(b) || musiMiec[b]) { daj(fuFind(a)); } if(musiMiec[a]) { daj(fuFind(b)); } musiNieMiec[a] = false; musiNieMiec[b] = false; graf[a].push_back(b); graf[b].push_back(a); fuUnion(a, b); } void query(int v) { chk(v); printf(musiMiec[v] ? "1" : musiNieMiec[v] ? "0" : "?"); } void take(int v) { auto vv = newNumber[v]; cntTaken[fuFind(vv)]++; musiNieMiec[vv] = true; musiMiec[vv] = false; newNumber[v] = ++n; musiNieMiec[n] = true; musiMiec[n] = false; rep[n] = n; members[n] = 1; } int main() { scanf("%d%d", &n, &q); init(); char c; int a, b; for(int i = 0; i < q; i++) { scanf(" %c", &c); if(c == '+') { scanf("%d%d", &a, &b); add(newNumber[a], newNumber[b]); } if(c == '-') { scanf("%d", &a); take(a); } if(c == '?') { scanf("%d", &a); query(newNumber[a]); } } return 0; } |
English