@@ -20,81 +20,84 @@ using namespace std;
2020#define snd second
2121#define all (c ) begin(c), end(c)
2222
23- struct undoable_union_find {
24- vector<int > p;
25- undoable_union_find (int n) : p(n, -1 ) { };
26- vector<tuple<int ,int ,int >> hist;
23+
24+ struct UndoableUnionFind {
25+ vector<int > parent;
26+ vector<tuple<int ,int ,int >> history;
27+ UndoableUnionFind (int n) : parent(n, -1 ) { };
2728 bool unite (int u, int v) {
28- if ((u = root (u)) == (v = root (v))) return false ;
29- if (p[u] > p[v]) swap (u, v);
30- hist.push_back (make_tuple (u, v, p[v]));
31- p[u] += p[v]; p[v] = u;
29+ u = root (u); v = root (v);
30+ if (u == v) return false ;
31+ if (parent[u] > parent[v]) swap (u, v);
32+ history.push_back (make_tuple (u, v, parent[v]));
33+ parent[u] += parent[v]; parent[v] = u;
3234 return true ;
3335 }
3436 void undo () {
35- int u, v, w; tie (u, v, w) = hist.back ();
36- hist.pop_back ();
37- p[v] = w;
38- p[u] -= p[v];
37+ int u, v, w;
38+ tie (u, v, w) = history.back ();
39+ history.pop_back ();
40+ parent[v] = w;
41+ parent[u] -= parent[v];
3942 }
4043 bool find (int u, int v) { return root (u) == root (v); }
41- int root (int u) { for (; p [u] >= 0 ; u = p [u]); return u ; }
42- int size (int u) { return -p [root (u)]; }
44+ int root (int u) { return parent [u] < 0 ? u : parent [u] = root (parent[u]) ; }
45+ int size (int u) { return -parent [root (u)]; }
4346};
4447
45- struct offline_dynamic_connectivity {
48+
49+ struct OfflineDynamicConnectivity {
4650 int n;
47- undoable_union_find uf;
48- offline_dynamic_connectivity (int n) : n(n), uf(n) { }
51+ UndoableUnionFind uf;
52+ OfflineDynamicConnectivity (int n) : n(n), uf(n) { }
4953
50- typedef pair<int ,int > edge ;
51- vector<edge > query;
54+ typedef pair<int ,int > Edge ;
55+ vector<Edge > query;
5256 vector<int > ans;
53- map<edge , vector<pair<int ,int >>> appear;
57+ map<Edge , vector<pair<int ,int >>> appear;
5458
55- void add_edge (int u, int v) {
59+ void addEdge (int u, int v) {
5660 if (u > v) swap (u, v);
5761 appear[{u,v}].push_back ({query.size (), 1 <<30 });
5862 }
59- void erase_edge (int u, int v) {
63+ void eraseEdge (int u, int v) {
6064 if (u > v) swap (u, v);
6165 appear[{u,v}].back ().snd = query.size ();
6266 }
63- int is_connected (int u, int v) {
67+ int isConnected (int u, int v) {
6468 query.push_back ({u,v});
6569 return query.size ()-1 ;
6670 }
67-
68- vector<set<edge>> es;
69- void insert (int l, int r, int k, int s, int t, edge e) {
71+ vector<set<Edge>> edges;
72+ void insert (int l, int r, int k, int s, int t, Edge e) {
7073 s = max (s, l); t = min (r, t);
7174 if (s >= t) return ;
7275 if (s == l && t == r) {
73- es [k].insert (e);
76+ edges [k].insert (e);
7477 } else {
7578 insert (l, (l+r)/2 , 2 *k+1 , s, t, e);
7679 insert ((l+r)/2 , r, 2 *k+2 , s, t, e);
77- if (es [2 *k+1 ].count (e) && es [2 *k+2 ].count (e)) {
78- es [2 *k+1 ].erase (e);
79- es [2 *k+2 ].erase (e);
80- es [k].insert (e);
80+ if (edges [2 *k+1 ].count (e) && edges [2 *k+2 ].count (e)) {
81+ edges [2 *k+1 ].erase (e);
82+ edges [2 *k+2 ].erase (e);
83+ edges [k].insert (e);
8184 }
8285 }
8386 }
8487 void rec (int l, int r, int k) {
8588 if (l >= r) return ;
86- for (edge e: es [k]) uf.unite (e.fst , e.snd );
89+ for (Edge e: edges [k]) uf.unite (e.fst , e.snd );
8790 if (l+1 == r) {
8891 ans[l] = uf.find (query[l].fst , query[l].snd );
8992 } else {
9093 rec (l, (l+r)/2 , 2 *k+1 );
9194 rec ((l+r)/2 , r, 2 *k+2 );
9295 }
93- for (edge e: es [k]) uf.undo ();
96+ for (Edge e: edges [k]) uf.undo ();
9497 }
9598 void solve () {
9699 int q = query.size ();
97- es .resize (4 *q);
100+ edges .resize (4 *q);
98101 for (auto a: appear)
99102 for (auto b: a.snd )
100103 insert (0 , q, 0 , b.fst , b.snd , a.fst );
@@ -104,15 +107,15 @@ struct offline_dynamic_connectivity {
104107};
105108
106109int main () {
107- offline_dynamic_connectivity solver (3 );
108- solver.is_connected (0 ,1 );
109- solver.add_edge (0 ,1 );
110- solver.is_connected (0 ,1 );
111- solver.is_connected (1 ,2 );
112- solver.add_edge (1 ,2 );
113- solver.is_connected (0 ,2 );
114- solver.erase_edge (0 ,1 );
115- solver.is_connected (0 ,2 );
110+ OfflineDynamicConnectivity solver (3 );
111+ solver.isConnected (0 ,1 );
112+ solver.addEdge (0 ,1 );
113+ solver.isConnected (0 ,1 );
114+ solver.isConnected (1 ,2 );
115+ solver.addEdge (1 ,2 );
116+ solver.isConnected (0 ,2 );
117+ solver.eraseEdge (0 ,1 );
118+ solver.isConnected (0 ,2 );
116119 solver.solve ();
117120 for (int i = 0 ; i < solver.query .size (); ++i) {
118121 cout << solver.query [i].fst << " " << solver.query [i].snd << " " << solver.ans [i] << endl;
0 commit comments