[BZOJ 3673]可持久化并查集 by zky

Posted trisolaris

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ 3673]可持久化并查集 by zky相关的知识,希望对你有一定的参考价值。

[BZOJ 3673]可持久化并查集by zky

 

<题意概括>

一道可持久化并查集的裸题

 

<做法>

类似于普通并查集

只不过普通并查集用普通数组实现

而可持久化并查集用可持久化数组实现

 

<Code>

此处给出递归和迭代两种写法 

<Recursive>

技术分享图片
#include<cstdio>
#define Fast register
inline char Getchar(){
    static char BUF[16384],*S=BUF,*T=BUF;
    return(S==T)&&(T=(S=BUF)+fread(BUF,1,16384,stdin),S==T)?EOF:*S++;
}
inline int Getint(){
    Fast int s=0;Fast char c=Getchar(),w=0;
    while(c<48||c>57)c==45&&(w=1),c=Getchar();
    while(c>47&&c<58)s=s*10+c-48,c=Getchar();
    return w?-s:s;
}
struct Node{
    int key;
    Node *lson,*rson;
    Node(int key=0):key(key){}
    Node(Node*&o):key(o->key),lson(o->lson),rson(o->rson){}
}*root[20001];
#define ls(o) (o)->lson
#define rs(o) (o)->rson
inline void Build(Node*&o,const int&L,const int&R,const int*Arr){
    o=new Node;
    if(L==R){o->key=Arr[L];return;}
    Fast int Mid=(L+R)>>1;
    Build(ls(o),L,Mid,Arr);
    Build(rs(o),Mid+1,R,Arr);
}
inline void Modify(Node*&PostVersion,Node*&NewVersion,const int&L,const int&R,const int&Loc,const int&key){
    NewVersion=new Node(PostVersion);
    if(L==R){NewVersion->key=key;return;}
    Fast int Mid=(L+R)>>1;
    if(Loc<=Mid)Modify(ls(PostVersion),ls(NewVersion),L,Mid,Loc,key);
    else Modify(rs(PostVersion),rs(NewVersion),Mid+1,R,Loc,key);
}
inline int Query(Node*&o,const int&L,const int&R,int&k){
    if(L==R)return o->key;
    Fast int Mid=(L+R)>>1;
    if(k>Mid)return Query(rs(o),Mid+1,R,k);
    return Query(ls(o),L,Mid,k);
}
int uset[20001];
int N;
inline int Find(Node*&Version,int Loc){
    Fast int Fa;
    while((Fa=Query(Version,1,N,Loc))!=Loc)Loc=Fa;
    return Loc;
}
#define UnionSet(PostVersion,NewVersion,x,y) Modify(PostVersion,NewVersion,1,N,Find(PostVersion,x),Find(PostVersion,y))
#define SameSet(Version,x,y) (Find(Version,x)==Find(Version,y))
int main(){
    N=Getint();
    Fast int M=Getint(),opt,A,B;
    for(Fast int i=1;i<=N;++i)uset[i]=i;
    Build(*root,1,N,uset);
    for(Fast int i=1;i<=M;++i){
        opt=Getint(),A=Getint();
        if(opt==1)UnionSet(root[i-1],root[i],A,Getint());
        else if(opt==2)root[i]=root[A];
        else B=Getint(),putchar(SameSet(root[i]=root[i-1],A,B)?49:48),putchar(10);
    }
}
[BZOJ 3673]可持久化并查集 by zky

<Iterative>

技术分享图片
#include<cstdio>
#define Fast register
inline char Getchar(){
    static char BUF[16384],*S=BUF,*T=BUF;
    return(S==T)&&(T=(S=BUF)+fread(BUF,1,16384,stdin),S==T)?EOF:*S++;
}
inline int Getint(){
    Fast int s=0;Fast char c=Getchar(),w=0;
    while(c<48||c>57)c==45&&(w=1),c=Getchar();
    while(c>47&&c<58)s=s*10+c-48,c=Getchar();
    return w?-s:s;
}
struct Node{
    int key;
    Node *lson,*rson;
    Node(int key=0):key(key){}
    Node(Node*&o):key(o->key),lson(o->lson),rson(o->rson){}
}*root[20001];
#define ls(o) (o)->lson
#define rs(o) (o)->rson
inline void Build(Node*&o,const int&L,const int&R,const int*Arr){
    o=new Node;
    if(L==R){o->key=Arr[L];return;}
    Fast int Mid=(L+R)>>1;
    Build(ls(o),L,Mid,Arr);
    Build(rs(o),Mid+1,R,Arr);
}
inline void Modify(Node*&PostVersion,Node*&NewVersion,int L,int R,const int&Loc,const int&key){
    Fast Node**Post=&PostVersion,**New=&NewVersion;
    Fast int Mid;
    while(L!=R){
        Mid=(L+R)>>1;
        *New=new Node(*Post);
        if(Loc<=Mid)Post=&(ls(*Post)),New=&(ls(*New)),R=Mid;
        else Post=&(rs(*Post)),New=&(rs(*New)),L=Mid+1;
    }
    *New=new Node(*Post);
    (*New)->key=key;
}
inline int Query(Node*Version,int L,int R,const int&k){
    Fast int Mid;
    while(L!=R){
        Mid=(L+R)>>1;
        if(k<=Mid)Version=ls(Version),R=Mid;
        else Version=rs(Version),L=Mid+1;
    }
    return Version->key;
}
int uset[20001];
int N;
inline int Find(Node*&Version,int Loc){
    Fast int Fa;
    while((Fa=Query(Version,1,N,Loc))!=Loc)Loc=Fa;
    return Loc;
}
#define UnionSet(PostVersion,NewVersion,x,y) Modify(PostVersion,NewVersion,1,N,Find(PostVersion,x),Find(PostVersion,y))
#define SameSet(Version,x,y) (Find(Version,x)==Find(Version,y))
int main(){
    N=Getint();
    Fast int M=Getint(),opt,A,B;
    for(Fast int i=1;i<=N;++i)uset[i]=i;
    Build(*root,1,N,uset);
    for(Fast int i=1;i<=M;++i){
        opt=Getint(),A=Getint();
        if(opt==1)UnionSet(root[i-1],root[i],A,Getint());
        else if(opt==2)root[i]=root[A];
        else B=Getint(),putchar(SameSet(root[i]=root[i-1],A,B)?49:48),putchar(10);
    }
}
[BZOJ 3673]可持久化并查集 by zky

 

 

 

 

以上是关于[BZOJ 3673]可持久化并查集 by zky的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3674可持久化并查集加强版&BZOJ 3673可持久化并查集 by zky 用可持久化线段树破之

[BZOJ3674]可持久化并查集加强版&[BZOJ3673]可持久化并查集 by zky

[bzoj3673][可持久化并查集 by zky] (rope(可持久化数组)+并查集=可持久化并查集)

3673: 可持久化并查集 by zky

BZOJ-3673&3674可持久化并查集 可持久化线段树 + 并查集

[bzoj] 3673 3674 可持久化并查集 || 可持久化数组