This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub beet-aizu/library
// verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2235 #include<bits/stdc++.h> using namespace std; #define call_from_test #include "../../graph/dynamicconnectivity.cpp" #undef call_from_test signed main(){ cin.tie(0); ios::sync_with_stdio(0); int n,q; cin>>n>>q; DynamicConnectivity dc(n,q); vector<int> ts(q),us(q),vs(q); for(int i=0;i<q;i++){ cin>>ts[i]>>us[i]>>vs[i]; if(ts[i]==1) dc.insert(i,us[i],vs[i]); if(ts[i]==2) dc.erase( i,us[i],vs[i]); } dc.build(); auto f= [&](int x){ if(x>=q||ts[x]!=3) return; cout<<(dc.puf.same(us[x],vs[x])?"YES":"NO")<<endl; }; dc.exec(f); return 0; }
#line 1 "test/aoj/2235.test.cpp" // verification-helper: PROBLEM http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2235 #include<bits/stdc++.h> using namespace std; #define call_from_test #line 1 "graph/dynamicconnectivity.cpp" #line 3 "graph/dynamicconnectivity.cpp" using namespace std; #endif //BEGIN CUT HERE struct PersistentUnionFind{ using T = pair<int, int>; vector<int> rs,ps; stack<T> st; PersistentUnionFind(int n): rs(n,1),ps(n,0){iota(ps.begin(),ps.end(),0);} int find(int x){ return x==ps[x]?ps[x]:find(ps[x]); } bool same(int x,int y){ return find(x)==find(y); } void unite(int x,int y){ x=find(x);y=find(y); st.emplace(-1,-1); if(x==y) return; if(rs[x]<rs[y]) swap(x,y); rs[x]+=rs[y]; ps[y]=x; st.top()=T(x,y); } void undo(int t=1){ for(int i=0;i<t;i++){ int x,y; tie(x,y)=st.top();st.pop(); if(x<0) continue; rs[x]-=rs[y]; ps[y]=y; } } }; struct DynamicConnectivity{ using edge = pair<int, int>; using range = pair<int, int>; int q; PersistentUnionFind puf; vector< vector<edge> > edges; vector <pair<range, edge> > prc; map<edge, int> cnt,app; DynamicConnectivity(int n,int q_):q(1),puf(n){ while(q<q_) q<<=1; edges.resize(q*2); } void insert(int t,int u,int v){ edge e=minmax(u,v); if(cnt[e]++==0) app[e]=t; } void erase(int t,int u,int v){ edge e=minmax(u,v); if(--cnt[e]==0) prc.emplace_back(range(app[e],t),e); } void add(int a,int b,edge e,int k,int l,int r){ if(r<=a or b<=l) return; if(a<=l and r<=b){ edges[k].emplace_back(e); return; } int m=(l+r)>>1; add(a,b,e,(k<<1)|0,l,m); add(a,b,e,(k<<1)|1,m,r); } void add(range r,edge e){ add(r.first,r.second,e,1,0,q); } void build(){ for(auto &e:cnt){ if(!e.second) continue; prc.emplace_back(range(app[e.first],q),e.first); } for(auto &s:prc) add(s.first,s.second); } template<typename F> void exec(const F &f,int k=1){ for(auto &e:edges[k]) puf.unite(e.first,e.second); if(k<q){ exec(f,(k<<1)|0); exec(f,(k<<1)|1); }else{ f(k-q); } puf.undo(edges[k].size()); } }; //END CUT HERE #ifndef call_from_test signed main(){ return 0; } #endif #line 8 "test/aoj/2235.test.cpp" #undef call_from_test signed main(){ cin.tie(0); ios::sync_with_stdio(0); int n,q; cin>>n>>q; DynamicConnectivity dc(n,q); vector<int> ts(q),us(q),vs(q); for(int i=0;i<q;i++){ cin>>ts[i]>>us[i]>>vs[i]; if(ts[i]==1) dc.insert(i,us[i],vs[i]); if(ts[i]==2) dc.erase( i,us[i],vs[i]); } dc.build(); auto f= [&](int x){ if(x>=q||ts[x]!=3) return; cout<<(dc.puf.same(us[x],vs[x])?"YES":"NO")<<endl; }; dc.exec(f); return 0; }