码迷,mamicode.com
首页 > 其他好文 > 详细

[模板] 可持久化并查集

时间:2019-02-06 17:05:15      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:int   并且   www.   数组   date   ++   ref   cst   cstring   

传送门

基于可持久化数组 = 可持久化线段树 = 主席树,使用按秩合并,并且查询操作返回点的位置,可以重复使用,能减少查询次数。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 6000005

int fa[MAXN],d[MAXN],root[MAXN];
int lson[MAXN],rson[MAXN];
int N,M,cnt = 0;

inline int read() {
    int flag = 1,num = 0; char ch = getchar();
    while(ch>'9'||ch<'0') {
        if(ch=='-') flag = -1;
        ch = getchar();
    }
    while(ch>='0'&&ch<='9') {
        num = num*10 + ch - 48;
        ch = getchar();
    }
    return num*flag;
}

void Build(int& rt,int l,int r) {
    rt = ++cnt;
    if(l==r) {
        fa[rt] = l;
        return;
    }
    int mid = (l+r) >> 1;
    Build(lson[rt],l,mid); Build(rson[rt],mid+1,r);
}

void update(int& rt,int pre,int l,int r,int x,int val) {
    rt = ++cnt; fa[rt] = fa[pre]; d[rt] = d[pre];
    lson[rt] = lson[pre]; rson[rt] = rson[pre];
    if(l==r) {
        fa[rt] = val;
        return;
    }
    int mid = (l+r) >> 1;
    if(x<=mid) update(lson[rt],lson[pre],l,mid,x,val);
    else update(rson[rt],rson[pre],mid+1,r,x,val);
}

int query(int rt,int l,int r,int x) {
    if(l==r) return rt;
    int mid = (l+r) >> 1;
    if(x<=mid) return query(lson[rt],l,mid,x);
    else return query(rson[rt],mid+1,r,x);
}

void add(int rt,int l,int r,int x) {
    if(l==r) {
        ++d[rt];
        return;
    }
    int mid = (l+r) >> 1;
    if(x<=mid) add(lson[rt],l,mid,x);
    else add(rson[rt],mid+1,r,x);
}

int find(int x,int ver) {
    int pos = query(root[ver],1,N,x);
    return x==fa[pos] ? pos : find(fa[pos],ver);
}

int main() {

    N = read(); M = read();    
    Build(root[0],1,N);

    int u,v,opt;
    for(int i=1;i<=M;++i) {
        opt = read(); u = read();
        if(opt==1) {
            v = read(); root[i] = root[i-1];
            int uu = find(u,i-1),vv = find(v,i-1);
            if(fa[uu]==fa[vv]) continue;
            if(d[uu]>d[vv]) std::swap(uu,vv);
            update(root[i],root[i-1],1,N,fa[uu],fa[vv]);
            if(d[uu]==d[vv]) add(root[i],1,N,fa[vv]);
        }
        else if(opt==2) root[i] = root[u];
        else {
            v = read(); root[i] = root[i-1];
            puts( fa[find(u,i-1)]==fa[find(v,i-1)] ? "1" : "0" );
        }
    }
    return 0;
}

[模板] 可持久化并查集

标签:int   并且   www.   数组   date   ++   ref   cst   cstring   

原文地址:https://www.cnblogs.com/Neworld2002/p/10353797.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!