forked from beet-aizu/library
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdynamicconnectivity.cpp
126 lines (114 loc) · 2.53 KB
/
dynamicconnectivity.cpp
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
#include<bits/stdc++.h>
using namespace std;
using Int = long long;
//BEGIN CUT HERE
struct PersistentUnionFind{
using T = pair<int, int>;
int n;
vector<int> r,p;
stack<T> st;
PersistentUnionFind(){}
PersistentUnionFind(int sz):n(sz),r(sz,1),p(sz,0){iota(p.begin(),p.end(),0);}
int find(int x){
return x==p[x]?p[x]:find(p[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(r[x]<r[y]) swap(x,y);
r[x]+=r[y];
p[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;
r[x]-=r[y];
p[y]=y;
}
}
};
struct DynamicConnectivity{
using edge = pair<int, int>;
using range = edge;
int n,q;
PersistentUnionFind puf;
vector<vector<edge> > edges;
vector<pair<range, edge> > prc;
map<edge, int> cnt,app;
DynamicConnectivity(){}
DynamicConnectivity(int n,int q_):n(n),q(1),puf(n){
while(q<q_) q<<=1;
edges.resize(q*2-1);
}
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,const edge &e,int k,int l,int r){
if(r<=a||b<=l) return;
if(a<=l&&r<=b){
edges[k].emplace_back(e);
return;
}
int m=(l+r)>>1;
add(a,b,e,k*2+1,l,m);
add(a,b,e,k*2+2,m,r);
}
void add(range &r,const edge &e){
add(r.first,r.second,e,0,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);
}
void exec(function<void(int)> &f,int k=0){
for(auto &e:edges[k])
puf.unite(e.first,e.second);
if(k<q-1){
exec(f,k*2+1);
exec(f,k*2+2);
}else{
int x=k-(q-1);
f(x);
}
puf.undo(edges[k].size());
}
};
//END CUT HERE
signed main(){
int n,q;
cin>>n>>q;
DynamicConnectivity dc(n,q);
vector<int> t(q),u(q),v(q);
for(int i=0;i<q;i++){
cin>>t[i]>>u[i]>>v[i];
if(t[i]==1) dc.insert(i,u[i],v[i]);
if(t[i]==2) dc.erase(i,u[i],v[i]);
}
dc.build();
function<void(int)> f=[&](int x){
if(x>=q||t[x]!=3) return;
cout<<(dc.puf.same(u[x],v[x])?"YES":"NO")<<endl;
};
dc.exec(f);
return 0;
}
/*
verified on 2018/01/07
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2235
*/