并查集按秩合并
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define PII pair<int, int>
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
//freopen("E://oneout.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
//std::ios::sync_with_stdio(false);
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e4 + 10;//30000000
const int maxm = (maxn << 5);
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int n, m;
int dad[maxn], dep[maxn];
int find_dad(int i){
return dad[i] == i ? i : find_dad(dad[i]);
}
void hebin(int x, int y){
int zx = find_dad(x);
int zy = find_dad(y);
if(zx != zy){
if(dep[zx] < dep[zy]) dad[zx] = zy;
else{
dad[zy] = zx;
if(dep[zx] == dep[zy]) dep[zx] ++;
}
}
}
int main(){
int op, u, v;
scanf("%d %d", &n, &m);
for(int i = 1 ; i <= n ; ++ i) dad[i] = i, dep[i] = 0;
for(int i = 1 ; i <= m ; ++ i){
scanf("%d %d %d", &op, &u, &v);
if(op == 1) hebin(u, v);
else{
if(find_dad(u) == find_dad(v)) cout << "Y" << endl;
else cout << "N" << endl;
}
}
return 0;
}
可持久化数组
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define PII pair<int, int>
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
//freopen("E://oneout.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
//std::ios::sync_with_stdio(false);
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e6 + 10;//30000000
const int maxm = (maxn << 5);
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int n, m, cnt;
int root[maxm], ls[maxm], rs[maxm], val[maxm];
int a[maxn];
int build(int l, int r){
int root = ++ cnt;
if(l == r){
val[root] = a[l];
return root;
}
int mid = (l + r) >> 1;
ls[root] = build(l, mid);
rs[root] = build(mid + 1, r);
return root;
}
int update(int x, int y, int l, int r, int root){
int id = ++ cnt;
ls[id] = ls[root]; rs[id] = rs[root];
int mid = (l + r) >> 1;
if(l == r){
val[id] = y;
return id;
}
if(x <= mid) ls[id] = update(x, y, l, mid, ls[id]);
if(x > mid) rs[id] = update(x, y, mid + 1, r, rs[id]);
return id;
}
int query(int x, int l, int r, int root){
if(l == r) return val[root];
int mid = (l + r) >> 1;
if(x <= mid) return query(x, l, mid, ls[root]);
if(x > mid) return query(x, mid + 1, r, rs[root]);
}
int main(){
int k, op, x, y;
scanf("%d %d", &n, &m);
for(int i = 1 ; i <= n ; ++ i){
scanf("%d", &a[i]);
}
root[0] = build(1, n);
for(int i = 1 ; i <= m ; ++ i){
scanf("%d %d", &k, &op);
if(op == 1){
scanf("%d %d", &x, &y);
root[i] = update(x, y, 1, n, root[k]);
}
else{
scanf("%d", &x);
cout << query(x, 1, n, root[k]) << endl;
root[i] = root[k];
}
}
return 0;
}
可持久化并查集
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cstdlib>
#include<cmath>
#include<stack>
#include<map>
#include<string>
#include<vector>
#include<set>
#include<bitset>
#include<algorithm>
#include<ctime>
using namespace std;
#define ll long long
#define lb long double
#define INF 0x3f3f3f3f
#define LINF 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define clr(a, b) memset(a, b, sizeof(a))
#define lowbit(x) x & -x
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define PB push_back
#define POP pop_back
#define max_ll 9223372036854775807
#define PII pair<int, int>
#define random(x) (rand()%x)
//srand((ll)time(0));
//freopen("E://one.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取
//freopen("E://oneout.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中
//std::ios::sync_with_stdio(false);
const double eps = 1e-14;
const double pi = acos(-1);
const int maxn = 1e5 + 10;//30000000
const int maxm = (maxn << 5);
const ll mod = 1e9 + 7;
const int hash_mod = 19260817;
int n, m, cnt;
int dad[maxm], ls[maxm], rs[maxm], dep[maxm], root[maxm];
int build(int l, int r){
int root = ++ cnt;
int mid = (l + r) >> 1;
if(l == r){
dad[root] = l;
return root;
}
ls[root] = build(l, mid);
rs[root] = build(mid + 1, r);
return root;
}
int hebin(int root, int l, int r, int s, int f){
int id = ++ cnt;
ls[id] = ls[root]; rs[id] = rs[root];
if(l == r){
dad[id] = f;
dep[id] = dep[root];
return id;
}
int mid = (l + r) >> 1;
if(s <= mid) ls[id] = hebin(ls[id], l, mid, s, f);
if(s > mid) rs[id] = hebin(rs[id], mid + 1, r, s, f);
return id;
}
void update(int root, int l, int r, int x){
if(l == r){
dep[root] ++;
return;
}
int mid = (l + r) >> 1;
if(x <= mid) update(ls[root], l, mid, x);
if(x > mid) update(rs[root], mid + 1, r, x);
}
int query(int root, int l, int r, int pos){
if(l == r) return root;
int mid = (l + r) >> 1;
if(pos <= mid) return query(ls[root], l, mid, pos);
if(pos > mid) return query(rs[root], mid + 1, r, pos);
}
int find_dad(int root, int i){
int x = query(root, 1, n, i);
return dad[x] == i ? x : find_dad(root, dad[x]);
}
int main(){
scanf("%d %d", &n, &m);
root[0] = build(1, n);
int op, u, v, x, y;
for(int i = 1 ; i <= m ; ++ i){
scanf("%d", &op);
if(op == 1){
scanf("%d %d", &u, &v);
root[i] = root[i-1];
int zx = find_dad(root[i], u);
int zy = find_dad(root[i], v);
if(dad[zx] != dad[zy]){
if(dep[zx] > dep[zy]) swap(zx, zy);
root[i] = hebin(root[i], 1, n, dad[zx], dad[zy]);
if(dep[zx] == dep[zy]) update(root[i], 1, n, dad[zy]);
}
}
else if(op == 2){
scanf("%d", &x);
root[i] = root[x];
}
else if(op == 3){
scanf("%d %d", &x, &y);
root[i] = root[i-1];
int zx = find_dad(root[i], x);
int zy = find_dad(root[i], y);
if(dad[zx] == dad[zy]) cout << "1" << endl;
else cout << "0" << endl;
}
}
return 0;
}