可持久化并查集

并查集按秩合并

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值