-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdsuf.cpp
More file actions
131 lines (99 loc) · 2.97 KB
/
dsuf.cpp
File metadata and controls
131 lines (99 loc) · 2.97 KB
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
127
128
129
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> //required
#include <ext/pb_ds/tree_policy.hpp> //required
// template starts
using namespace __gnu_pbds; //required
using namespace std;
template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// ordered_set <int> s;
// s.find_by_order(k); returns the (k+1)th smallest element
// s.order_of_key(k); returns the number of elements in s strictly less than k
#define MOD (1000000000+7) // change as required
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
#define all(x) x.begin(), x.end()
#define print(vec,l,r) for(int i = l; i <= r; i++) cout << vec[i] <<" "; cout << endl;
#define input(vec,N) for(int i = 0; i < (N); i++) cin >> vec[i];
#define debug(x) cerr << #x << " = " << (x) << endl;
#define leftmost_bit(x) (63-__builtin_clzll(x))
#define rightmost_bit(x) __builtin_ctzll(x)
#define set_bits(x) __builtin_popcountll(x)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef long long int ll;
// start of highly risky #defines
#define int ll // disable when you want to make code a bit faster
#define endl '\n' // disable when dealing with interactive problems
// End of highly risky #defines
class DSUF{
public:
vector<int> dist, sz;
vector<int> par;
int distinct_comp;
int N;
DSUF(int n){
N = n;
distinct_comp = n;
dist.resize(n);
par.resize(n);
sz.resize(n);
for(int i = 0; i < N; i++){
dist[i] = 0;
par[i] = i;
sz[i] = 1;
}
}
int get_key(int k){
if(k == par[k]) return k;
return par[k] = get_key(par[k]);
}
void merge(int k1, int k2){
int head_k1 = get_key(k1);
int head_k2 = get_key(k2);
if(head_k1 == head_k2) return;
distinct_comp--;
// I want to connect k1 to k2, so k2 should be bigger
if(dist[head_k1] > dist[head_k2]) swap(head_k1, head_k2); // union by depth
// if(sz[head_k1] > sz[head_k2]) swap(head_k1, head_k2); // union by size
// use one of the union heuristics, both are practically the same
if(dist[head_k1] == dist[head_k2]) dist[head_k2]++;
sz[head_k2] += sz[head_k1];
par[head_k1] = head_k2;
}
bool is_connected(int k1, int k2){
return get_key(k1) == get_key(k2);
}
};
// template ends here
void solve(){
// code starts from here
int N, Q;
cin >> N >> Q;
DSUF dsu(N);
while(Q--){
int t, x,y;
cin >> t >> x >> y;
if(t == 0){
dsu.merge(x,y);
}else{
cout << dsu.is_connected(x,y) << endl;
}
}
}
clock_t startTime;
double getCurrentTime() {
return (double)(clock() - startTime) / CLOCKS_PER_SEC;
}
signed main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
//startTime = clock();
int T = 1;
// cin >> T;
while(T--){
solve();
}
//cout << getCurrentTime() << endl;
return 0;
}