可持久化并查集
Posted yyys-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可持久化并查集相关的知识,希望对你有一定的参考价值。
可持久化就用主席树实现,学习自这篇博客

#include<bits/stdc++.h> #define N 4000005 using namespace std; int read() int x=0,f=1;char s=getchar(); while(s<‘0‘||s>‘9‘)if(s==‘-‘)f=-1;s=getchar(); while(s>=‘0‘&&s<=‘9‘)x=x*10+s-‘0‘;s=getchar(); return x*f; int ndnum,n; int fa[N],lc[N],rc[N],dep[N],root[N]; void build(int k,int l,int r)//维护的是fa if(l==r)fa[k]=l;return; int mid=(l+r)>>1; build(lc[k]=++ndnum,l,mid); build(rc[k]=++ndnum,mid+1,r); int query(int k,int L,int R,int pos) if(L==R) return k; int mid=(L+R)>>1; if(pos<=mid)return query(lc[k],L,mid,pos); else return query(rc[k],mid+1,R,pos); int get(int k,int x) int now=query(k,1,n,x); if(fa[now]==x)return now; return get(k,fa[now]); void merge(int last,int &k,int L,int R,int pos,int f) k=++ndnum;lc[k]=lc[last];rc[k]=rc[last];//复制 if(L==R) fa[k]=f; dep[k]=dep[last]; return; int mid=(L+R)>>1; if(pos<=mid)merge(lc[last],lc[k],L,mid,pos,f); else merge(rc[last],rc[k],mid+1,R,pos,f); void update(int k,int L,int R,int pos) if(L==R)dep[k]++;return; int mid=(L+R)>>1; if(pos<=mid)update(lc[k],L,mid,pos); else update(rc[k],mid+1,R,pos); int main() n=read();int m=read(); build(root[0],1,n); for(int i=1;i<=m;++i) int op=read(); if(op==1) int a=read(),b=read(); root[i]=root[i-1]; int posx=get(root[i],a); int posy=get(root[i],b); if(fa[posx]==fa[posy])continue; if(dep[posx]>dep[posy])swap(posx,posy); merge(root[i-1],root[i],1,n,fa[posx],fa[posy]); if(dep[posx]==dep[posy])update(root[i],1,n,fa[posy]); //因为不可能出现深度相同的两个点,所以要把其中一个点深度+1,由于是深度小的合到深度大的上,所以把深度小的增加深度 else if(op==2) int x=read(); root[i]=root[x]; else int a=read(),b=read(); root[i]=root[i-1]; int posx=get(root[i],a); int posy=get(root[i],b); if(fa[posx]==fa[posy])printf("1\\n"); else printf("0\\n");
以上是关于可持久化并查集的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ-3673&3674可持久化并查集 可持久化线段树 + 并查集