#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define MAX_N 300003
#define MAX_M 1000003
#ifndef DEB_VAL
#define DEB_VAL 0
#endif
#define DEB if(debug)
#define MP make_pair
#define PB push_back
#define FT first
#define SD second
int debug = DEB_VAL;
int n,q,a,b,k;
char sign[5];
int res[MAX_N+MAX_M];
int sets[MAX_N+MAX_M];
int par[MAX_N+MAX_M];
int ranks[MAX_N+MAX_M];
int qu[MAX_N+MAX_M];
int qu_c;
int s_a,s_b;
int main() {
scanf("%d %d",&n,&q);
k=n+1;
for(int i=1;i<=n;i++) {
sets[i]=i;
ranks[i]=1;
par[i]=i;
}
for(int i=0;i<q;i++) {
scanf("%s", sign);
if(sign[0] == '+') {
//add edge
scanf("%d %d",&a,&b);
s_a=sets[a];
s_b=sets[b];
//find root s_a
qu_c=0;
while(par[s_a]!=s_a) {
qu[qu_c++]=s_a;
s_a=par[s_a];
}
while(qu_c>0) {
par[qu[--qu_c]]=s_a;
}
//find root s_b
qu_c=0;
while(par[s_b]!=s_b) {
qu[qu_c++]=s_b;
s_b=par[s_b];
}
while(qu_c>0) {
par[qu[--qu_c]]=s_b;
}
//if root a == root b -> all have
if(s_a==s_b) {
res[s_a]=1;
} else {
//else connect
if(res[s_a]==1 || res[s_b]==1) {
res[s_a]=res[s_b]=1;
} else {
res[s_a]=res[s_b]=-1;
}
if(ranks[s_a]>ranks[s_b]) {
par[s_b]=s_a;
ranks[s_a]+=ranks[s_b];
} else {
par[s_a]=s_b;
ranks[s_b]+=ranks[s_a];
}
}
} else if(sign[0] == '?') {
//answer
scanf("%d",&a);
s_a=sets[a];
//find root a
qu_c=0;
while(par[s_a]!=s_a) {
qu[qu_c++]=s_a;
s_a=par[s_a];
}
while(qu_c>0) {
par[qu[--qu_c]]=s_a;
}
//return result root a
if(res[s_a]==1) {
printf("1");
} else if(res[s_a]==0) {
printf("0");
} else {
if(ranks[s_a]==1) {
printf("0");
} else {
printf("?");
}
}
} else {
//disconnect
scanf("%d",&a);
s_a=sets[a];
//find root a
qu_c=0;
while(par[s_a]!=s_a) {
qu[qu_c++]=s_a;
s_a=par[s_a];
}
while(qu_c>0) {
par[qu[--qu_c]]=s_a;
}
//wyciagamy
sets[a]=k;
ranks[k]=1;
res[k]=0;
par[k]=k;
//wywalamy ze zbioru
ranks[s_a]--;
k++;
}
}
printf("\n");
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 120 121 122 123 124 125 126 127 128 129 130 131 132 | #include<cstdio> #include<algorithm> #include<vector> using namespace std; #define MAX_N 300003 #define MAX_M 1000003 #ifndef DEB_VAL #define DEB_VAL 0 #endif #define DEB if(debug) #define MP make_pair #define PB push_back #define FT first #define SD second int debug = DEB_VAL; int n,q,a,b,k; char sign[5]; int res[MAX_N+MAX_M]; int sets[MAX_N+MAX_M]; int par[MAX_N+MAX_M]; int ranks[MAX_N+MAX_M]; int qu[MAX_N+MAX_M]; int qu_c; int s_a,s_b; int main() { scanf("%d %d",&n,&q); k=n+1; for(int i=1;i<=n;i++) { sets[i]=i; ranks[i]=1; par[i]=i; } for(int i=0;i<q;i++) { scanf("%s", sign); if(sign[0] == '+') { //add edge scanf("%d %d",&a,&b); s_a=sets[a]; s_b=sets[b]; //find root s_a qu_c=0; while(par[s_a]!=s_a) { qu[qu_c++]=s_a; s_a=par[s_a]; } while(qu_c>0) { par[qu[--qu_c]]=s_a; } //find root s_b qu_c=0; while(par[s_b]!=s_b) { qu[qu_c++]=s_b; s_b=par[s_b]; } while(qu_c>0) { par[qu[--qu_c]]=s_b; } //if root a == root b -> all have if(s_a==s_b) { res[s_a]=1; } else { //else connect if(res[s_a]==1 || res[s_b]==1) { res[s_a]=res[s_b]=1; } else { res[s_a]=res[s_b]=-1; } if(ranks[s_a]>ranks[s_b]) { par[s_b]=s_a; ranks[s_a]+=ranks[s_b]; } else { par[s_a]=s_b; ranks[s_b]+=ranks[s_a]; } } } else if(sign[0] == '?') { //answer scanf("%d",&a); s_a=sets[a]; //find root a qu_c=0; while(par[s_a]!=s_a) { qu[qu_c++]=s_a; s_a=par[s_a]; } while(qu_c>0) { par[qu[--qu_c]]=s_a; } //return result root a if(res[s_a]==1) { printf("1"); } else if(res[s_a]==0) { printf("0"); } else { if(ranks[s_a]==1) { printf("0"); } else { printf("?"); } } } else { //disconnect scanf("%d",&a); s_a=sets[a]; //find root a qu_c=0; while(par[s_a]!=s_a) { qu[qu_c++]=s_a; s_a=par[s_a]; } while(qu_c>0) { par[qu[--qu_c]]=s_a; } //wyciagamy sets[a]=k; ranks[k]=1; res[k]=0; par[k]=k; //wywalamy ze zbioru ranks[s_a]--; k++; } } printf("\n"); return 0; } |
English