#include <iostream> #include <unordered_set> #include <vector> #include <cassert> constexpr int max_N=300001; int tree[2000000]; int my_val[2000000], free_val=max_N; int status[max_N];//0->no, 1->maybe, 2->yes std::unordered_set<int> t[max_N]; int find(int k){ if (tree[k]==k)return k; return tree[k]=find(tree[k]); } std::vector<int> tmp; void dfs(int start, int prev){ tmp.push_back(start); for (auto a:t[start]){ if (a!=prev)dfs(a,start); } } void update(int k){ dfs(k,k); for (auto a:tmp){ status[a]=2; tree[my_val[a]]=my_val[a]; t[a].clear(); } tmp.clear(); } int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(0); int n, q; std::cin>>n>>q; for (size_t i=1; i<=n; ++i){ tree[i]=i; my_val[i]=i; } for (size_t i=0; i<q; ++i){ char k; std::cin>>k; if (k=='+'){ int a, b; std::cin>>a>>b; if (status[a]==2){ status[b]=2; update(b); continue; } if (status[b]==2){ status[a]=2; update(a); continue; } if (find(my_val[a])==find(my_val[b])){ status[a]=2; status[b]=2; update(a); }else{ status[a]=1; status[b]=1; tree[find(my_val[a])]=find(my_val[b]); t[a].insert(b); t[b].insert(a); } } if (k=='-'){ int a; std::cin>>a; if (status[a]==1){ if (t[a].size()==1){ int other=*t[a].begin(); if (t[other].size()==1){ status[a]=0; status[other]=0; tree[my_val[a]]=my_val[a]; tree[my_val[other]]=my_val[other]; t[a].clear(); t[other].clear(); }else{ t[other].erase(a); t[a].erase(other); } }else{ for (auto k:t[a])t[k].erase(a); auto it=t[a].begin(), it2=t[a].begin(); ++it2; while (it2!=t[a].end()){ t[*it].insert(*it2); t[*it2].insert(*it); ++it, ++it2; } t[a].clear(); } } status[a]=0; my_val[a]=free_val; tree[my_val[a]]=free_val; ++free_val; } if (k=='?'){ int a; std::cin>>a; if (status[a]==0)std::cout<<'0'; if (status[a]==1)std::cout<<'?'; if (status[a]==2)std::cout<<'1'; } } std::cout<<'\n'; }
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 | #include <iostream> #include <unordered_set> #include <vector> #include <cassert> constexpr int max_N=300001; int tree[2000000]; int my_val[2000000], free_val=max_N; int status[max_N];//0->no, 1->maybe, 2->yes std::unordered_set<int> t[max_N]; int find(int k){ if (tree[k]==k)return k; return tree[k]=find(tree[k]); } std::vector<int> tmp; void dfs(int start, int prev){ tmp.push_back(start); for (auto a:t[start]){ if (a!=prev)dfs(a,start); } } void update(int k){ dfs(k,k); for (auto a:tmp){ status[a]=2; tree[my_val[a]]=my_val[a]; t[a].clear(); } tmp.clear(); } int main(){ std::ios_base::sync_with_stdio(false); std::cin.tie(0); int n, q; std::cin>>n>>q; for (size_t i=1; i<=n; ++i){ tree[i]=i; my_val[i]=i; } for (size_t i=0; i<q; ++i){ char k; std::cin>>k; if (k=='+'){ int a, b; std::cin>>a>>b; if (status[a]==2){ status[b]=2; update(b); continue; } if (status[b]==2){ status[a]=2; update(a); continue; } if (find(my_val[a])==find(my_val[b])){ status[a]=2; status[b]=2; update(a); }else{ status[a]=1; status[b]=1; tree[find(my_val[a])]=find(my_val[b]); t[a].insert(b); t[b].insert(a); } } if (k=='-'){ int a; std::cin>>a; if (status[a]==1){ if (t[a].size()==1){ int other=*t[a].begin(); if (t[other].size()==1){ status[a]=0; status[other]=0; tree[my_val[a]]=my_val[a]; tree[my_val[other]]=my_val[other]; t[a].clear(); t[other].clear(); }else{ t[other].erase(a); t[a].erase(other); } }else{ for (auto k:t[a])t[k].erase(a); auto it=t[a].begin(), it2=t[a].begin(); ++it2; while (it2!=t[a].end()){ t[*it].insert(*it2); t[*it2].insert(*it); ++it, ++it2; } t[a].clear(); } } status[a]=0; my_val[a]=free_val; tree[my_val[a]]=free_val; ++free_val; } if (k=='?'){ int a; std::cin>>a; if (status[a]==0)std::cout<<'0'; if (status[a]==1)std::cout<<'?'; if (status[a]==2)std::cout<<'1'; } } std::cout<<'\n'; } |