#include<iostream>
#include<unordered_map>
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define FORD(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
const int MAXN = 300000;
int T[1+MAXN], F[1+MAXN], L[1+MAXN], R[1+MAXN];
int n, q, a, b, c, d, m;
char ch;
unordered_map<int,int> S;
int main(void) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> q;
FOR(i, 1, n) { T[i]=i; F[i]=0; L[i]=i; R[i]=i; S[i]=i; }
m = n;
REP(i, q) {
// if (i % 10000 == 0) cerr << "i=" << i << endl;
cin >> ch;
if (ch == '+') {
cin >> a >> b;
if (T[a] != T[b]) {
if (S[T[a]] > S[T[b]]) { c=a;a=b;b=c; }
int F_ab = (F[a] == 1 || F[b] == 1) ? 1 : -1;
int T_a = T[a], T_b = T[b];
{ int j = a; do { T[j] = T_b; j = L[j]; } while (j!=a); }
if (F[a] != F_ab) { int j = a; do { F[j] = F_ab; j = L[j]; } while (j!=a); }
if (F[b] != F_ab) { int j = b; do { F[j] = F_ab; j = L[j]; } while (j!=b); }
int R_a = R[a]; R[a] = b;
int L_b = L[b]; L[b] = a;
L[R_a] = L_b; R[L_b] = R_a;
S[T_b] += S[T_a];
} else if (F[a] != 1) {
// fossilize the tree once
int j = a; do { F[j]=1 ; j=L[j]; } while (j!=a);
}
} else if (ch == '-') {
cin >> c;
int vtx = 0;
int j = c; if (F[c] == -1) do { vtx++; d=j ; j = L[j]; } while (j!=c && vtx <= 2);
F[c] = 0;
T[c] = ++m;
S[m] = 1;
int L_c = L[c], R_c = R[c]; R[L_c] = R_c; L[R_c] = L_c; L[c] = R[c] = c;
if (vtx == 2) {
F[d] = 0;
T[d] = ++m;
S[m] = 1;
int L_d = L[d], R_d = R[d]; R[L_d] = R_d; L[R_d] = L_d; L[d] = R[d] = d;
}
} else if (ch == '?') {
cin >> d;
if (F[d] >= 0) {
cout << F[d];
} 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 | #include<iostream> #include<unordered_map> #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for(int i=(a);i<=(b);++i) #define FORD(i,a,b) for(int i=(a);i>=(b);--i) using namespace std; const int MAXN = 300000; int T[1+MAXN], F[1+MAXN], L[1+MAXN], R[1+MAXN]; int n, q, a, b, c, d, m; char ch; unordered_map<int,int> S; int main(void) { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n >> q; FOR(i, 1, n) { T[i]=i; F[i]=0; L[i]=i; R[i]=i; S[i]=i; } m = n; REP(i, q) { // if (i % 10000 == 0) cerr << "i=" << i << endl; cin >> ch; if (ch == '+') { cin >> a >> b; if (T[a] != T[b]) { if (S[T[a]] > S[T[b]]) { c=a;a=b;b=c; } int F_ab = (F[a] == 1 || F[b] == 1) ? 1 : -1; int T_a = T[a], T_b = T[b]; { int j = a; do { T[j] = T_b; j = L[j]; } while (j!=a); } if (F[a] != F_ab) { int j = a; do { F[j] = F_ab; j = L[j]; } while (j!=a); } if (F[b] != F_ab) { int j = b; do { F[j] = F_ab; j = L[j]; } while (j!=b); } int R_a = R[a]; R[a] = b; int L_b = L[b]; L[b] = a; L[R_a] = L_b; R[L_b] = R_a; S[T_b] += S[T_a]; } else if (F[a] != 1) { // fossilize the tree once int j = a; do { F[j]=1 ; j=L[j]; } while (j!=a); } } else if (ch == '-') { cin >> c; int vtx = 0; int j = c; if (F[c] == -1) do { vtx++; d=j ; j = L[j]; } while (j!=c && vtx <= 2); F[c] = 0; T[c] = ++m; S[m] = 1; int L_c = L[c], R_c = R[c]; R[L_c] = R_c; L[R_c] = L_c; L[c] = R[c] = c; if (vtx == 2) { F[d] = 0; T[d] = ++m; S[m] = 1; int L_d = L[d], R_d = R[d]; R[L_d] = R_d; L[R_d] = L_d; L[d] = R[d] = d; } } else if (ch == '?') { cin >> d; if (F[d] >= 0) { cout << F[d]; } else { cout << '?'; } } } cout << endl; return 0; } |
English