# include <bits/stdc++.h>
# define For(i, l, r) for(int i = (l); i <= (r); i++)
# define Rep(i, n) For(i, 0, (n) - 1)
# define size(x) (ll)x.size()
# define MAXSZ 300005
# define all(x) x.begin(),x.end()
using namespace std;
typedef int ll;
typedef long double ld;
const ll inf = 1e9 + 7;
const ll mod = 1e9 + 7;
ll n , m , k , q , t;
vector<ll> col(MAXSZ) , root(MAXSZ) , Rank(MAXSZ);
vector<vector<ll> >g(MAXSZ);
void init() {
For (i , 1 , n) {
root[i] = i;
Rank[i] = 1;
col[i] = 0;
}
}
ll get_r(ll x , ll odj) {
Rank[x] -= odj;
if (root[x] == x) return x;
else return get_r(root[x] , odj);
}
void clear(ll v) {
ll r = get_r(v , 0);
queue<ll>q;
q.push(r);
while (!q.empty()) {
ll v = q.front();
q.pop();
root[v] = v;
Rank[v] = 1;
col[v] = 1;
for (auto to : g[v]) {
q.push(to);
}
g[v].clear();
}
}
pair<ll , ll> Union(ll r1 , ll r2) {
if (Rank[r1] < Rank[r2]) swap(r1 , r2);
root[r2] = r1;
g[r1].push_back(r2);
return {r1 , r2};
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> q;
init();
while (q--) {
char c;
cin >> c;
if (c == '+') {
ll ai , bi;
cin >> ai >> bi;
if (col[ai] || col[bi]) {
if (col[ai]) swap(ai , bi);
clear(ai);
continue;
}
ll r1 = get_r(ai , 0) , r2 = get_r(bi , 0);
if (r1 == r2 || ai == bi) {
clear(r1);
} else {
auto [rr1 , rr2] = Union(r1 , r2);
Rank[rr1] += Rank[rr2];
}
} else if (c == '-') {
ll ci;
cin >> ci;
ll rci = get_r(ci , 1);
col[ci] = 0;
ll up = (root[ci] == ci ? -1 : root[ci]);
ll down = -1;
if (size(g[ci]) > 0) {
down = g[ci][0];
For (i , 1 , size(g[ci]) - 1) {
auto [new_down , prev] = Union(down , g[ci][i]);
down = new_down;
Rank[new_down] += Rank[prev];
}
g[ci].clear();
}
root[ci] = ci;
Rank[ci] = 1;
if (up != -1) {
Rep (i , size(g[up])) if (g[up][i] == ci) {
swap(g[up][i] , g[up].back());
g[up].pop_back();
break;
}
}
if (up != -1 && down != -1) {
root[down] = up;
g[up].push_back(down);
} else if (down != -1) {
root[down] = down;
}
} else {
ll di;
cin >> di;
if (root[di] == di && Rank[di] == 1) cout << col[di];
else cout << '?';
}
}
}
//odjgoadfhfoav hash1 i hash2 (hash1 * 1e9 + hash
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 | # include <bits/stdc++.h> # define For(i, l, r) for(int i = (l); i <= (r); i++) # define Rep(i, n) For(i, 0, (n) - 1) # define size(x) (ll)x.size() # define MAXSZ 300005 # define all(x) x.begin(),x.end() using namespace std; typedef int ll; typedef long double ld; const ll inf = 1e9 + 7; const ll mod = 1e9 + 7; ll n , m , k , q , t; vector<ll> col(MAXSZ) , root(MAXSZ) , Rank(MAXSZ); vector<vector<ll> >g(MAXSZ); void init() { For (i , 1 , n) { root[i] = i; Rank[i] = 1; col[i] = 0; } } ll get_r(ll x , ll odj) { Rank[x] -= odj; if (root[x] == x) return x; else return get_r(root[x] , odj); } void clear(ll v) { ll r = get_r(v , 0); queue<ll>q; q.push(r); while (!q.empty()) { ll v = q.front(); q.pop(); root[v] = v; Rank[v] = 1; col[v] = 1; for (auto to : g[v]) { q.push(to); } g[v].clear(); } } pair<ll , ll> Union(ll r1 , ll r2) { if (Rank[r1] < Rank[r2]) swap(r1 , r2); root[r2] = r1; g[r1].push_back(r2); return {r1 , r2}; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> n >> q; init(); while (q--) { char c; cin >> c; if (c == '+') { ll ai , bi; cin >> ai >> bi; if (col[ai] || col[bi]) { if (col[ai]) swap(ai , bi); clear(ai); continue; } ll r1 = get_r(ai , 0) , r2 = get_r(bi , 0); if (r1 == r2 || ai == bi) { clear(r1); } else { auto [rr1 , rr2] = Union(r1 , r2); Rank[rr1] += Rank[rr2]; } } else if (c == '-') { ll ci; cin >> ci; ll rci = get_r(ci , 1); col[ci] = 0; ll up = (root[ci] == ci ? -1 : root[ci]); ll down = -1; if (size(g[ci]) > 0) { down = g[ci][0]; For (i , 1 , size(g[ci]) - 1) { auto [new_down , prev] = Union(down , g[ci][i]); down = new_down; Rank[new_down] += Rank[prev]; } g[ci].clear(); } root[ci] = ci; Rank[ci] = 1; if (up != -1) { Rep (i , size(g[up])) if (g[up][i] == ci) { swap(g[up][i] , g[up].back()); g[up].pop_back(); break; } } if (up != -1 && down != -1) { root[down] = up; g[up].push_back(down); } else if (down != -1) { root[down] = down; } } else { ll di; cin >> di; if (root[di] == di && Rank[di] == 1) cout << col[di]; else cout << '?'; } } } //odjgoadfhfoav hash1 i hash2 (hash1 * 1e9 + hash |
English