• 可持久化并查集模板


    测试题目

    洛谷模板题传送门

    Code:

    //By zuiyumeng
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define Re register
    #define Ms(a,b) memset((a),(b),sizeof(a))
    #define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
    #define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
    using namespace std;
    
    inline int read() { 
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
        while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
        return x*f;
    }
    
    const int N=100010;
    int n,m,cnt;
    int fa[N*20],root[N*20],ls[N*20],rs[N*20],dep[N*20];
    
    #define mid ((l+r)>>1)
    void build(int &cur,int l,int r) {
        cur=++cnt; 
        if(l==r) {fa[cur]=l;return ;}
        build(ls[cur],l,mid); build(rs[cur],mid+1,r);
    }
    
    void merge(int las,int &cur,int l,int r,int u,int v) {
        cur=++cnt; ls[cur]=ls[las]; rs[cur]=rs[las];
        if(l==r) fa[cur]=v,dep[cur]=dep[las];
        else if(u<=mid) merge(ls[las],ls[cur],l,mid,u,v); //注意las和cur跟着一起跳
        else merge(rs[las],rs[cur],mid+1,r,u,v);
    }
    
    void update(int cur,int l,int r,int u) {
        if(l==r) dep[cur]++;
        else if(u<=mid) update(ls[cur],l,mid,u);
        else update(rs[cur],mid+1,r,u);
    }
    
    int getnm(int cur,int l,int r,int u) {
        if(l==r) return cur;
        else if(u<=mid) return getnm(ls[cur],l,mid,u);
        else return getnm(rs[cur],mid+1,r,u);   
    }
    
    int getro(int rt,int u) {
        int num=getnm(rt,1,n,u);
        return fa[num]==u?num:getro(rt,fa[num]); //注意这里返回的是num,因为对应值可以由fa[num]得到
    }
    
    int main() {
        n=read(); m=read();
        build(root[0],1,n);
        Fo(i,1,m) {
            int opt=read();
            if(opt==1) {
                int u=read(),v=read();
                int ru=getro(root[i-1],u),rv=getro(root[i-1],v);
                if(dep[ru]>dep[rv]) swap(ru,rv);
                merge(root[i-1],root[i],1,n,fa[ru],fa[rv]);
                if(dep[ru]==dep[rv]) update(root[i],1,n,fa[rv]);
            }
            else if(opt==2) root[i]=root[read()];
            else {
                int u=read(),v=read();
                root[i]=root[i-1];
                int ru=getro(root[i],u),rv=getro(root[i],v);
                if(ru==rv) cout<<1<<endl;
                else cout<<0<<endl;
            }
        }
        return 0;
    }
    
    本文版权归作者所有,未经允许不得转载。
  • 相关阅读:
    最小生成树之 Prim 算法
    Linux通过ps命令找到进程并kill当前进程
    M6G2C Cortex®A7工控核心板SIMCOM4G模块移植流程
    Spring事件监听机制源码解析
    Pytorch损失函数总结
    目标检测任务理解与总结
    [炼丹术]EfficientDet训练模型学习总结
    [炼丹术]DeepLabv3+训练模型学习总结
    可视化经典模型的对比实验总结
    基于COCO数据集验证的目标检测算法天梯排行榜
  • 原文地址:https://www.cnblogs.com/zuiyumeng/p/13545824.html
Copyright © 2020-2023  润新知