library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub beet-aizu/library

:heavy_check_mark: test/aoj/2235.test.cpp

Depends on

Code

// 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;
}
Back to top page