可持久化并查集模板

测试题目

洛谷模板题传送门

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;
}
posted @ 2020-08-22 15:25  醉语梦  阅读(127)  评论(0编辑  收藏  举报